当前位置: 首页 > news >正文

Linux(线程库和线程封装)

线程库和线程封装

  • 1 理解线程库
    • 1.1 线程库被加载到内存
    • 1.2 线程ID
    • 1.3 线程栈
  • 2 线程封装(用C++封装线程)

1 理解线程库

1.1 线程库被加载到内存

在这里插入图片描述

(1)上面的这份代码我们上一节已经编写过了,结果也在图中展示出来了,我们可以发现所谓的tid其实就是一个地址

在这里插入图片描述

(2)前面我们学过线程的各种函数是依赖于库的,库也要被加载到内存中,它也会通过页表被映射到进程地址空间中的共享区,因为线程共享进程地址空间中的各种区,所以共享区也被共享,所以所有线程都能够看到线程库,所以新线程和主线程都能使用各种线程函数

1.2 线程ID

(1)Linux中根本就没有线程这个概念,只有LWP,但是我们用户要用线程,所以OS是封装了线程接口,但是如果我们想要线程属性呢(id,优先级,状态,栈大小、、、、)?从OS的角度出发,是不是应该将线程的属性集维护起来,在创建线程的同时就将其属性填充好,用户只需要获得线程的属性,而不是获得LWP的属性

(2)另一个进程里的线程属性需不需要被维护?所以库为了管理所有的线程属性集,需要先描述再组织(tcb),所以OS维护的是PCB,库维护的是tcb

(3)一个线程库内部维护了所有线程的属性集合,所以线程ID就是线程属性在线程库中的地址

在这里插入图片描述

(3)下面这张图就是共享区内的线程库示意图,其中我们可以将线程库理解为数组存储tcb,我们只需要找到每一个线程tcb的开始地址就可以获取到整个tcb的内容

在这里插入图片描述

(4)这个struct pthrea里面一定封装了lwb
(5)线程之间上下文独立,但栈只有一个,所以我们每一个线程的栈都是被独立创建出来的,结论就是进程地址空间上的栈是主线程的栈,而新线程的栈都是被动态申请的
(6)所谓的线程局部存储就是通过关键字 --thread ,让变量在每一个线程中存在一份(只能修饰内置类型)

在这里插入图片描述

上图中第一行的value只存在一份,也就是每一个线程拿到的变量地址都是一样的,其中一个线程中的该值发生改变,所有线程中的都发生变化,而下面一行中的value每个线程拿到的地址都不一样,并且值不会随一个线程改变而改变(errno就是基于这种方式实现的)

1.3 线程栈

在这里插入图片描述

总之线程栈默认大小为8M,其不能动态增长

在这里插入图片描述

2 线程封装(用C++封装线程)

(1)封装的目的:1、为了让我们更熟练使用线程函数的接口 2、实现多线程更方便
(2)demo样例:

makefile:

在这里插入图片描述

Thread.hpp:(不能传参数 )

#include <iostream>
#include <string>
#include <functional>
#include <sys/types.h>
#include <unistd.h>namespace THreadModule
{using func_t = std::function<void()>;static int number = 1;enum class TSTATUS // 枚举线程的状态,因为线程结束,线程类不一定结束{NEW,RUNNING,STOP};class Thread{private:static void *Routine(void *args) // 成员方法!第一个参数是this指针{//_func();// 之所以创建时最后一个传this,是因为Routine无法使用_func函数,// 因为它需要this才行,但是Routinue被我们转化为了static函数,没有this指针了Thread *t = static_cast<Thread *>(args);t->_func();t->_status = TSTATUS::RUNNING;return nullptr;}void EnableDetach() // 是否可分离{_joinable = false;}public:Thread(func_t func) : _func(func), _status(TSTATUS::NEW), _joinable(true){_name = "Thread-" + std::to_string(number++); // 给线程起名字_pid = getpid();}bool Start() // 线程启动{if (_status == TSTATUS::NEW){int n = ::pthread_create(&_tid, nullptr, Routine, this); // 为什么用this?if (n != 0)return false;}return true;}bool Stop() // 线程终止{if (_status == TSTATUS::RUNNING){int n = pthread_cancel(_tid);if (n != 0)return false;_status = TSTATUS::STOP;}return true;}bool Join() // 等待线程结束{if (_joinable){int n = ::pthread_join(_tid, nullptr);if (n != 0)return false;_status = TSTATUS::STOP;}return true;}void Detach() // 线程分离{EnableDetach();pthread_detach(_tid);}bool IsJoinable() // 是否可等待{return _joinable;}std::string Name(){return _name;}~Thread(){}private:std::string _name; // 线程名字pthread_t _tid;    // 线程idpid_t _pid;        // 线程属于哪个进程bool _joinable;    // 是否是分离的,默认不是func_t _func;      // 线程执行什么函数TSTATUS _status;   // 线程状态};
}

测试的main.cc
在这里插入图片描述

多线程的main.cc:

在这里插入图片描述

传参数的thread.hpp:(看懂即可,我们正常用不到参数),我只给出了不同的部分,其他部分完全一致

namespace THreadModule
{static int number = 1;enum class TSTATUS // 枚举线程的状态,因为线程结束,线程类不一定结束{NEW,RUNNING,STOP};template <typename T>class Thread{using func_t = std::function<void(T)>;private:static void *Routine(void *args) // 成员方法!第一个参数是this指针{//_func();// 之所以创建时最后一个传this,是因为Routine无法使用_func函数,// 因为它需要this才行,但是Routinue被我们转化为了static函数,没有this指针了Thread<T> *t = static_cast<Thread<T> *>(args);t->_func(t->_data);t->_status = TSTATUS::RUNNING;return nullptr;}public:Thread(func_t func, T data) : _func(func), _data(data), _status(TSTATUS::NEW), _joinable(true){_name = "Thread-" + std::to_string(number++); // 给线程起名字_pid = getpid();}private:std::string _name; // 线程名字pthread_t _tid;    // 线程idpid_t _pid;        // 线程属于哪个进程bool _joinable;    // 是否是分离的,默认不是func_t _func;      // 线程执行什么函数TSTATUS _status;   // 线程状态T _data;};
}

参数的传递:

在这里插入图片描述

http://www.dtcms.com/a/432083.html

相关文章:

  • 制作网站公司名称动漫制作专业在广西哪所院校最强
  • 网站后台cms南京的互联网公司
  • 西安工商注册网上平台株洲网站排名优化价格
  • 网站建设与运营 就业深夜的fm免费看
  • 汽车配件外贸网站爱企查商标查询
  • 诸城盟族网站建设做招牌的广告公司
  • 数字信号处理 第一章(离散时间信号与系统)【下】
  • 【星海出品】程序的存储访问 - Q-A解答
  • 怎么查网站服务器优化seo方案
  • 10.1 面向长序列建模的高效注意力机制
  • 怎么自己做网站挣钱网站cn和com有什么区别
  • java线上问题排查-OOM内存溢出
  • 阿里云国际站官网如何让网站不被收录
  • Notepad++下载安装图文教程(附安装包)
  • ProtoBuf使用手册(入门)
  • 网站服务器 电信推广码怎么填
  • 数据驱动+AI赋能:互联网项目管理全流程的技术破局与方法论实践
  • 贵阳网站建设设计手机做任务的网站
  • AI大模型:(三)1.4 Dify聊天助手快速搭建智能淘宝店小二
  • dw做网站怎么排版网站开发应财务如何记账
  • 网站开发流行工具如何知道一个网站做的什么推广
  • 网站建设方面书籍手机网站导航特效
  • 网站策划包括哪些内容中国哪家网站做仿古做的好
  • 常用的建一个网站要多少钱四川省和城乡建设厅网站
  • 笔记:标准化和归一化的学习
  • 培训学校类网站建设方案1软装包括哪些
  • 计算机网络【第三章-数据链路层】
  • 网站 建设 内容 安排济南seo整站优化厂家
  • Ubuntu 中获取指定软件依赖安装包
  • 利用CountDownLatch批量处理解决实际业务问题