【Linux】线程库

一、线程库管理

tid其实是一个地址 

void* start(void* args)
{const char* name = (const char *)args;while(true){printf("我是新线程 %s ,我的地址:0x%lx\n",name,pthread_self());sleep(1);}return nullptr;
}int main()
{pthread_t tid1;pthread_create(&tid1,nullptr,start,(void*)"thread-1");printf("我是主线程,我的地址:0x%lx\n",pthread_self());void* ret = nullptr;pthread_join(tid1,&ret);return 0;
}
zxw@hcss-ecs-cc58:~/linux_-ubuntu/class/lesson7$ ./mythread 
我是主线程,我的地址:0x7f9dbdc333c0
我是新线程 thread-1 ,我的地址:0x7f9dbdc2f640
我是新线程 thread-1 ,我的地址:0x7f9dbdc2f640
我是新线程 thread-1 ,我的地址:0x7f9dbdc2f640

首先,我们知道pthread. h不是操作系统的接口,而是原生线程库。那么用户创建的线程,操作系统无法管理,则需要线程库来进行管理。他从系统中获取轻量级进程相关属性,从用户中也获取一些属性,这样就先描述起来了,再通过数据结构将线程组织起来,就将线程管理好了。

那么线程库如何管理呢,在哪管理呢?  

在进程地址空间中,通过 mmap (共享区)加载了动态库,我们使用的 pthread 库就在该区域。pthread 库会管理进程中的每一个线程,它使用一系列的数据结构(如线程控制块)来组织和维护线程的相关信息。

每个线程还拥有独立的栈空间,主线程的栈由操作系统在进程启动时自动创建,位于进程地址空间的默认栈区;而通过 pthread_create 创建的其他线程,其栈空间默认由操作系统在进程地址空间的线程私有区域进行分配。

当调用 pthread 相关函数时,实际上是对 pthread 库所管理的这些数据结构进行访问和操作,从而实现对线程的创建、同步、销毁等管理功能。

那么现在,我们也可以理解 pthread_t tid 是什么了,他不就是每一个线程在进程地址空间的起始地址嘛,我们pthread_create 对tid进行写入,因为需要创建对应的数据结构,找到起始地址,然后返回,后续用户要继续对线程进行控制,等待啊,终止啊,分离啊,取消啊。都需要传入tid,也就是能找到在进程地址空间的位置后,才可以处理。

二、线程的局部存储 

int g_val = 100;void *TreadFun(void *arg)
{while (1){cout << "我是一个新线程,g_val: " << g_val << ",&g_val: " << &g_val << endl;g_val++;sleep(1);}return nullptr;
}int main()
{pthread_t tid;pthread_create(&tid, NULL, TreadFun, (void *)"Thread 1");while (1){cout << "我是一个主线程,g_val: " << g_val << ",&g_val: " << &g_val << endl;sleep(1);}pthread_join(tid,nullptr);
}
zxw@hcss-ecs-cc58:~/linux_-ubuntu/class/lesson7/Pthread$ ./testThread 
我是一个主线程,g_val: 100,&g_val: 0x55a1a3616014
我是一个新线程,g_val: 100,&g_val: 0x55a1a3616014
我是一个主线程,g_val: 101,&g_val: 0x55a1a3616014
我是一个新线程,g_val: 101,&g_val: 0x55a1a3616014
我是一个主线程,g_val: 102,&g_val: 0x55a1a3616014
我是一个新线程,g_val: 102,&g_val: 0x55a1a3616014
我是一个主线程,g_val: 103,&g_val: 0x55a1a3616014
我是一个新线程,g_val: 103,&g_val: 0x55a1a3616014

如果我们给全局变量前添加上__thread,GCC/G++编译器提供的一个扩展,用于声明线程局部存储变量。 

__thread int g_val = 100;

重新执行程序,发现地址发生改变

我是一个主线程,g_val: 100,&g_val: 0x7f8c2a39b3bc
我是一个新线程,g_val: 102,&g_val: 0x7f8c2a39763c
我是一个主线程,g_val: 100,&g_val: 0x7f8c2a39b3bc
我是一个新线程,g_val: 103,&g_val: 0x7f8c2a39763c
我是一个主线程,g_val: 100,&g_val: 0x7f8c2a39b3bc
我是一个新线程,g_val: 104,&g_val: 0x7f8c2a39763c

因为我们添加的__thread 会在G++编译时,给每个线程的局部存储空间里将变量拷贝进程,私有一份,于是每个线程自己管理自己的那一份资源。 

__thread只能修饰内置类型,如string这种数据结构和自定义类型无法处理。

 三、线程封装 

#ifndef _THREAD_HPP__
#define _THREAD_HPP__
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdio>
using namespace std;namespace MyThread
{template <typename T>using func_t = function<void(T)>;static int number = 1;enum TSTATUS{NEW,RUNNING,STOP};template <typename T>class Thread{private:// 成员方法! void* Routinue(Thread* this,void* args)static void *Routinue(void *args){Thread<T> *t = (Thread<T> *)args;t->_status = TSTATUS::RUNNING;t->_func(t->_data);return nullptr;}void EnableDetach(){_joinable = false;}public:Thread(func_t<T> func, T data) : _func(func), _status(TSTATUS::NEW), _joinable(true), _data(data){_name = "Thread-" + to_string(number++);_pid = getpid();}bool Start(){if (_status != TSTATUS::RUNNING){int n = ::pthread_create(&_tid, nullptr, Routinue, this);if (n != 0)return false;return true;}return false;}bool Stop(){if (_status == TSTATUS::RUNNING){int n = ::pthread_cancel(_tid);if (n != 0)return false;return true;}return false;}bool Join(){if (_joinable){int n = ::pthread_join(_tid, nullptr);if (n != 0)return false;_status = TSTATUS::STOP;return true;}return false;}void Detach(){EnableDetach();pthread_detach(_tid);}bool IsJoinable() { return _joinable; }string Name() { return _name; }~Thread(){}private:string _name;pthread_t _tid;pid_t _pid;bool _joinable; // 是否分离,默认不是func_t<T> _func;TSTATUS _status;T _data;};}#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39026.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能宠物饮水机WTL580微波雷达感应模块方案;便捷管理宠物饮水

一&#xff1a;宠物智能饮水与技术创新 1&#xff1a;非接触式感应 微波雷达模块实时检测宠物靠近行为&#xff0c;当宠物进入感应范围时&#xff0c;饮水机自动启动水泵&#xff0c;提供新鲜水流 2&#xff1a;多模式配置 感应距离&#xff1a;30-150cm可调&#xff0c;适应…

How to share files with Windows via samba in Linux mint 22

概述 Windows是大家日常使用最多的操作系统&#xff0c;在Windows主机之间&#xff0c;可以共享文件&#xff0c;那么如何在Windows主机与Linux主机之间共享文件呢&#xff1f; 要在Windows主机与Linux主机之间共享文件&#xff0c;我们可以借助Samba协议完成。借助Samba协议…

牛客周赛84 题解 Java ABCDE 仅供参考

A 小苯跑外卖 除一下看有没有余数 有余数得多一天 没余数正好 // github https://github.com/Dddddduo // github https://github.com/Dddddduo/acm-java-algorithm // github https://github.com/Dddddduo/Dduo-mini-data_structure import java.util.*; import java.io.*…

基于SpringBoot + Vue 的图书馆座位预约系统

SpringBoot 图书馆座位预约管理系统 自习室座位预约管理系统 javaSpringbootVUEredis 1. 开发环境&#xff1a; idea/eclipse、jdk1.8、maven、nodejs 2. 技术栈&#xff1a;java、springboot、Redis、mybatis、vue 3. 数据库&#xff1a; MySQL 有用户和管理员两个角色…

深入理解 lt; 和 gt;:HTML 实体转义的核心指南!!!

&#x1f6e1;️ 深入理解 < 和 >&#xff1a;HTML 实体转义的核心指南 &#x1f6e1;️ 在编程和文档编写中&#xff0c;< 和 > 符号无处不在&#xff0c;但它们也是引发语法错误、安全漏洞和渲染混乱的头号元凶&#xff01;&#x1f525; 本文将聚焦 <&#…

Vue 3 + TypeScript 实现视频播放与字幕功能:集成西瓜播放器 XGPlayer

文章目录 1. 前言&#xff1a;视频播放器的重要性2. 准备工作2.1 安装 Vue 3 项目2.2 安装 XGPlayer 和相关依赖 3. 实现视频播放3.1 初始化 XGPlayer 4. 添加字幕功能4.1 配置字幕 4.2 字幕文件格式5. 增加交互性完整的代码&#xff0c;仅供参考6. 总结 在现代 Web 开发中&…

Simple-BEV的bilinear_sample 作为view_transformer的解析,核心是3D-2D关联点生成

文件路径models/view_transformers 父类 是class BiLinearSample(nn.Module)基于https://github.com/aharley/simple_bev。 函数解析 函数bev_coord_to_feature_coord的功能 将鸟瞰图3D坐标通过多相机&#xff08;针孔/鱼眼&#xff09;内外参投影到图像特征平面&#xff0…

HTTP长连接与短连接的前世今生

HTTP长连接与短连接的前世今生 大家好&#xff01;作为一名在互联网摸爬滚打多年的开发者&#xff0c;今天想跟大家聊聊HTTP中的长连接和短连接这个话题。 记得我刚入行时&#xff0c;对这些概念一头雾水&#xff0c;希望这篇文章能帮助新入行的朋友少走些弯路。 什么是HTTP…

在Mac M1/M2芯片上完美安装DeepCTR库:避坑指南与实战验证

让推荐算法在Apple Silicon上全速运行 概述 作为推荐系统领域的最经常用的明星库&#xff0c;DeepCTR集成了CTR预估、多任务学习等前沿模型实现。但在Apple Silicon架构的Mac设备上&#xff0c;安装过程常因ARM架构适配、依赖库版本冲突等问题受阻。本文通过20次环境搭建实测…

c#知识点补充4

1.发布者订阅模式 发布者 订阅者 俩者直接的关联使用

3. 轴指令(omron 机器自动化控制器)——>MC_SetOverride

机器自动化控制器——第三章 轴指令 12 MC_SetOverride变量▶输入变量▶输出变量▶输入输出变量 功能说明▶时序图▶重启运动指令▶多重启动运动指令▶异常 MC_SetOverride 变更轴的目标速度。 指令名称FB/FUN图形表现ST表现MC_SetOverride超调值设定FBMC_SetOverride_instan…

Cocos Creator Shader入门实战(五):材质的了解、使用和动态构建

引擎&#xff1a;3.8.5 您好&#xff0c;我是鹤九日&#xff01; 回顾 前面的几篇文章&#xff0c;讲述的主要是Cocos引擎对Shader使用的一些固定规则&#xff0c;这里汇总下&#xff1a; 一、Shader实现基础是OpenGL ES可编程渲染管线&#xff0c;开发者只需关注顶点着色器和…

体育直播模板nba英超直播欧洲杯直播模板手机自适应

源码名称&#xff1a;体育直播模板nba英超直播欧洲杯直播模板手机自适应帝国cms 7.5模板 开发环境&#xff1a;帝国cms7.5 空间支持&#xff1a;phpmysql 带软件采集&#xff0c;可以挂着自动采集发布&#xff0c;无需人工操作&#xff01; 模板特点&#xff1a; 程序伪静态…

python基于spark的心脏病患分类及可视化(源码+lw+部署文档+讲解),源码可白嫖!

摘要 时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;汽车数据分析平台当然不能排除在外。本次我所开发的心脏病患分类及可视化系统是在实际应用和软件工程的开发原理之上&#xff0c;运用Pyth…

SAP 附件增删改查与文件服务器交互应用

【需求背景】 非SAP标准附件应用&#xff0c;自定义一套&#xff0c;跟公司内部文档服务器交互&#xff0c;支持各个应用场景的附件增删改查等。 每个附件在文件服务器上都有一个文件唯一ID作为关键字。 应用分两块&#xff1a;SAP GUI端&#xff0c;跟WDA Portal端应用 GU…

Linux__之__基于UDP的Socket编程网络通信

前言 本篇博客旨在使用Linux系统接口进行网络通信, 帮助我们更好的熟悉使用socket套接字网络通信, 学会了socket网络通信, 就能发现所谓网络, 不过都是套路而已, 话不多说, 让我们直接进入代码编写部分. 1. 事先准备 今天我们先来模拟实现一个echo demo, 也就是客户端向服务…

【Agent】Dify Docker 安装问题 INTERNAL SERVER ERROR

总结&#xff1a;建议大家选择稳定版本的分支&#xff0c;直接拉取 master 分支&#xff0c;可能出现一下后面更新代码导致缺失一些环境内容。 启动报错 一直停留在 INSTALL 界面 我是通过 Docker 进行安装的&#xff0c;由于项目开发者不严谨导致&#xff0c;遇到一个奇怪的…

unity开发效率提升笔记

本文将记录提升Unity开发效率的若干细节&#xff0c;持续更新 一.VSCode文件标签多行显示 1.File->Preference->Settings (快捷键Ctrl 逗号) 2.搜索workbench.editor.wrapTabs 3.勾选上这个单选开关 若依然不是多行 4.搜索workbench.editor.tabSizing,选择fi…

python每日十题(6)

列表操作函数有&#xff08;假设列表名为ls&#xff09;&#xff1a; len(ls)&#xff1a;返回列表ls的元素个数&#xff08;长度&#xff09;。min(ls)&#xff1a;返回列表ls的最小元素。max(ls)&#xff1a;返回列表ls的最大元素。list(x)&#xff1a;将x转变为列表类型。使…

【Java】TCP网络编程:从可靠传输到Socket实战

活动发起人小虚竹 想对你说&#xff1a; 这是一个以写作博客为目的的创作活动&#xff0c;旨在鼓励大学生博主们挖掘自己的创作潜能&#xff0c;展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴&#xff0c;那么&#xff0c;快来参加吧&#xff01…