【Linux】线程库

news2025/3/25 22:20:29

一、线程库管理

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.coloradmin.cn/o/2320755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物化视图详解:数据库性能优化的利器

物化视图&#xff08;Materialized View&#xff09;作为数据库性能优化的核心手段&#xff0c;通过预计算和存储查询结果&#xff0c;显著提升了复杂查询的效率。本文将深入剖析物化视图的工作原理、应用场景及最佳实践&#xff0c;帮助企业在合适的场景中充分发挥其性能优势。…

蓝桥杯备考-》单词接龙

很明显&#xff0c;这道题是可以用DFS来做的&#xff0c;我们直接暴力搜索&#xff0c;但是这里有很多点是我们需要注意的。 1.我们如何确定两个单词能接上&#xff1f; 比如touch和choose 应该合成为touchoose 就是这样两个单词&#xff0c;我们让一个指针指着第一个字符串…

计算机视觉yolov8模型应用-学习笔记

计算机视觉yolov8模型应用-学习笔记 YOLOv8是由Ultralytics公司在‌2023年1月10日‌发布的一款深度学习模型。它是YOLOv5的重大更新版本&#xff0c;支持图像分类、物体检测和实例分割任务。这一版本在发布前就受到了广泛关注&#xff0c;并在发布后迅速成为目标检测领域的热门…

【网络层协议】NAT技术内网穿透

IP地址数量限制 我们知道&#xff0c;IP地址&#xff08;IPv4&#xff09;是一个4字节32位的整数&#xff0c;那么一共只有2^32也就是接近43亿个IP地址&#xff0c;而TCP/IP协议栈规定&#xff0c;每台主机只能有一个IP地址&#xff0c;这就意味着&#xff0c;一共只有不到43亿…

深入理解 C++11 智能指针:独占、共享与弱引用的完美管理

文章目录 std::unique_ptr&#xff08;独占式智能指针&#xff09;std::shared_ptr&#xff08;共享式智能指针&#xff09;std::weak_ptr&#xff08;弱引用智能指针&#xff09;示例展示&#xff1a;智能指针的原理内存泄漏**什么是内存泄漏&#xff0c;内存泄漏的危害****如…

AI Agent开发大全第四课-提示语工程:从简单命令到AI对话的“魔法”公式

什么是提示语工程?一个让AI“听话”的秘密 如果你曾经尝试过用ChatGPT或者其他大语言模型完成任务,那么你一定遇到过这样的情况:明明你的问题是清晰的,但答案却离题万里;或者你认为自己提供的信息足够详尽,可结果还是不理想。问题出在哪?很多时候并不是因为AI不够聪明,…

大模型架构记录 【综述-文字版】

名词解释&#xff1a; Prompt &#xff1a;提示词&#xff0c;是一个非常关键的概念&#xff0c;它指的是用户输入的文本或指令&#xff0c;用于引导语言模型生成相应的回答或执行特定任务。 Prompt Engineering&#xff1a;&#xff08;提示工程&#xff09; 是一种通过设计…

【论文笔记】Transformer

Transformer 2017 年&#xff0c;谷歌团队提出 Transformer 结构&#xff0c;Transformer 首先应用在自然语言处理领域中的机器翻译任务上&#xff0c;Transformer 结构完全构建于注意力机制&#xff0c;完全丢弃递归和卷积的结构&#xff0c;这使得 Transformer 结构效率更高…

使用CSS3实现炫酷的3D翻转卡片效果

使用CSS3实现炫酷的3D翻转卡片效果 这里写目录标题 使用CSS3实现炫酷的3D翻转卡片效果项目介绍技术要点分析1. 3D空间设置2. 核心CSS属性3. 布局和定位 实现难点和解决方案1. 3D效果的流畅性2. 卡片内容布局3. 响应式设计 性能优化建议浏览器兼容性总结 项目介绍 在这个项目中…

SpringSecurity——基于角色权限控制和资源权限控制

目录 基于角色权限控制 1.1 自定义 UserDetailsService 1.2 加载用户角色 1.3. 给角色配置能访问的资源&#xff08;使用切面拦截&#xff0c;使用注解&#xff09; 总结 资源权限控制 2.2. 需要有一个用户&#xff1b;&#xff08;从数据库查询用户&#xff09; 2.2 基…

红宝书第十一讲:超易懂版「ES6类与继承」零基础教程:用现实例子+图解实现

红宝书第十一讲&#xff1a;超易懂版「ES6类与继承」零基础教程&#xff1a;用现实例子图解实现 资料取自《JavaScript高级程序设计&#xff08;第5版&#xff09;》。 查看总目录&#xff1a;红宝书学习大纲 一、ES6类的核心语法&#xff1a;把事物抽象成“模板” 想象你要设…

Python为Word文档添加书签并打包成exe

背景简述 由于一些工作场景&#xff0c;需要从多个Word文档中找到出现的关键词&#xff0c;并阅读关键词的上下文内容。文件可能几十个&#xff0c;手动操作太要命了。所以python尝试处理。 目录 背景简述思路第一步、功能实现结果验证 第二步、打包成exe2-1、基础准备2-2、打…

ROS导航工具包Navigation

一&#xff0c;安装 Navigation工具包包含在 navigation 元功能包中。你可以通过以下命令安装&#xff1a; sudo apt-get install ros-noetic-navigation 如果你使用的是其他ROS版本&#xff08;如Melodic&#xff09;&#xff0c;将 noetic 替换为对应的版本名称&#xff08…

资金管理策略思路

详细描述了完整交易策略的实现细节&#xff0c;主要包括输入参数、变量定义、趋势判断、入场与出场条件、止损与止盈设置等多个方面。 输入参数&#xff08;Input&#xff09;&#xff1a; EntryFrL (.6)&#xff1a;多头入场的前一日波动范围的倍数。 EntryFrS (.3)&#xff1…

工业软件的破局与重构:从技术依赖到自主创新的未来路径

工业软件作为现代工业的“神经与大脑”&#xff0c;不仅是制造业数字化转型的核心工具&#xff0c;更是国家工业竞争力的战略制高点。近年来&#xff0c;中国工业软件市场在政策驱动与技术迭代中迅猛发展&#xff0c;但核心技术受制于人的困境仍待突破。如何实现从“跟跑”到“…

常见中间件漏洞攻略-Tomcat篇

一、 CVE-2017-12615-Tomcat put方法任意文件写入漏洞 第一步&#xff1a;开启靶场 第二步&#xff1a;在首页抓取数据包&#xff0c;并发送到重放器 第三步&#xff1a;先上传尝试一个1.txt进行测试 第四步&#xff1a;上传后门程序 第五步&#xff1a;使用哥斯拉连接 二、后…

【Dive Into Stable Diffusion v3.5】2:Stable Diffusion v3.5原理介绍

【Dive Into Stable Diffusion v3.5】系列博文&#xff1a; 第1篇&#xff1a;开源项目正式发布——深入探索SDv3.5模型全参/LoRA/RLHF训练第2篇&#xff1a;Stable Diffusion v3.5原理介绍 目录 1 前言1.1 扩散模型的原理1.2 损失函数1.3 加噪流程1.4 推理流程1.5 negative pr…

英伟达黄仁勋2025GTC演讲深度解析:液冷GPU、AI工厂、机器人AI…...

目录 一、技术产品与架构升级&#xff1a;从芯片到算力工厂1. 新一代GPU与计算架构2. AI工厂与算力操作系统 二、AI技术演进&#xff1a;从生成式到物理AI1. AI发展的三大阶段2. 推理算力需求爆炸式增长 三、生态合作与行业落地1. CUDA生态与开源工具2. 跨行业合作案例 四、未来…

嵌入式项目:利用心知天气获取天气数据实验方案

【实验目的】 1、利用心知天气服务器获取指定位置天气数据 2、将天气数据解析并可视化显示到OLED屏幕 【实验原理】 【实验步骤】 官网注册

Ubuntu下用QEMU模拟运行OpenBMC

1、前言 在调试过程中&#xff0c;安装了很多依赖库&#xff0c;具体没有记录。关于kvm&#xff0c;也没理清具体有什么作用。本文仅记录&#xff0c;用QEMU成功的将OpenBMC跑起来的过程&#xff0c;做备忘&#xff0c;也供大家参考。 2、环境信息 VMware Workstation 15 Pro…