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

装配式建筑信息平台无忧seo博客

装配式建筑信息平台,无忧seo博客,wordpress和discuz关联,境外网站搭建文章目录 线程概念Linux中线程是否存在的讨论线程创建和线程控制线程的终止和等待#xff08;三种终止方式 pthread_join()的void**retval#xff09; 线程概念 线程就是进程内部的一个执行流#xff0c;线程在进程内运行#xff0c;线程在进程的地址空间内运行#xff0… 文章目录 线程概念Linux中线程是否存在的讨论线程创建和线程控制线程的终止和等待三种终止方式 pthread_join()的void**retval 线程概念 线程就是进程内部的一个执行流线程在进程内运行线程在进程的地址空间内运行拥有该进程的一部分资源。这句话一说可能老铁们直接蒙蔽线程就线程嘛怎么还在进程里面运行呢还在地址空间内运行而且拥有进程的一部分资源这都是什么鬼 如何看待线程在地址空间内运行呢实际进程就像一个封闭的屋子线程就是在屋子里面的人而地址空间就是一个个的窗户屋子外面就是进程对应的代码和数据一个屋子里面当然可以有多个人而且每个人都可以挑选一个窗户看看外面的世界。 在上面的例子中每个人挑选一个窗户实际就是将进程的资源分配给进程内部的多个执行流以前fork创建子进程的时候不就是将父进程的一部分代码块儿交给子进程运行吗子进程不就是一个执行流吗 而今天我们所谈到的线程道理也是类似我们可以将进程的资源划分给不同的线程让线程来执行某些代码块儿而线程就是进程内部的一个执行流。那么此时我们就可以通过地址空间页表的方式将进程的部分资源划分给每一个线程那么线程的执行粒度一定比之前的进程更细 Linux中线程是否存在的讨论 我们在思考一下如果Linux在内核中真的创建出了我们上面所谈论到的线程那么Linux就一定要管理内核中的这些线程既然是管理那就需要先描述再组织创建出真正的 TCB(Thread Create Block)结构体来描述线程线程被创建的目的不就是被执行被CPU调度吗既然所有的线程都要被调度那每个线程都应该有自己独立的thread_id独立的上下文状态优先级独立的栈(线程执行进程中的某一个代码块儿)等等那么大家不觉得熟悉吗单纯从CPU调度的角度来看线程和进程有太多重叠的地方了 所以Linux中就没有创建什么线程TCB结构体直接复用进程的PCB当作线程的描述结构体用PCB来当作Linux系统内部的线程。这么做的好处是什么呢如果要创建真正的线程结构体那就需要对其进行维护需要和进程构建好关系每个线程还需要和地址空间进行关联CPU调度进程和调度线程还不一样操作系统要对内核中大量的进程和线程做管理这样维护的成本太高了不利于系统的稳定性和健壮性所以直接复用PCB是一个很好的选择维护起来的成本很低因为直接复用原来的数据结构就可以实现线程。所以这也是Linux系统既稳定又高效成为世界上各大互联网公司服务器系统选择的原因。而windows系统内是真正有对应的TCB结构体的他确实创建出了真正的线程所以维护起来的成本就会很高这也是windows用的用的就卡起来或者蓝屏的原因因为不好维护啊实现的结构太复杂代码健壮性不高 在知道linux的线程实现方案之后我们又该如何理解线程这个概念呢现在PCB都已经不表示进程了而是代表线程。以前我们所学的进程概念是进程的内核数据结构进程对应的代码和数据但今天站在内核视角来看进程的概念实际可以被重构为承担分配系统资源的基本实体进程分配了哪些系统资源呢PCB虚存页表物存。所以进程到底是什么呢 那在linux中什么是线程呢线程是CPU调度的基本单位也就是struct task_struct{}PCB就是线程为进程中的执行流 那我们以前学习的进程概念是否和今天学习的进程概念冲突了呢当然没有以前的进程也是承担分配系统资源的基本实体只不过原来的进程内部只有一个PCB也就是只有一个执行流而今天我们所学的进程内部是有多个执行流多个PCB 所以 Linux内核中有没有真正意义上的线程 Linux用进程的PCB来模拟线程是完全属于自己实现的一套方案 站在CPU的角度来看每一个PCB都可以称之为轻量级进程因为它只需要PCB即可而进程承担分配的资源更多量级更重 Linux线程是CPU调度的基本单位进程是承担分配系统资源的基本实体 进程用来整体向操作系统申请资源线程负责向进程伸手要资源。如果线程向操作系统申请资源实质上也是进程在向操作系统要资源因为线程在进程内部运行是进程内部的一部分 Linux内核中虽然没有真正意义上的线程但虽无进程之名却有进程之实 程序员只认线程但Linux没有线程只有轻量级进程所以Linux无法直接提供创建线程的系统调用接口只能提供创建轻量级进程的接口 线程创建和线程控制 #include iostream #include string #includeunistd.husing namespace std;void *start_routine(void *arg) {string name static_castconst char *(arg);while (true){cout new thread: name endl;sleep(1);} } int main() {pthread_t tid;pthread_create(tid, nullptr, start_routine, (void *)thread-1);while (true){cout main thread endl;sleep(1);}return 0; }创建一个线程比较简单没什么含金量所以在线程控制这里选择创建一批线程来看看多个线程下的进程运行情况。 在线程的错误检查这里并不会设置全部变量errno道理也很简单线程出错了那其实就是进程出错了错误码这件事不应该是我线程来搞这是你进程的事情和我线程有什么关系所以线程也没有理由去设置全局变量errno他的返回值只表示成功或错误具体的返回状态其实是要通过pthread_join来获取的 创建一批线程也并不困难我们可以搞一个vector存放创建出来的每个线程的tid但从打印出来的新线程的编号可以看出来打印的非常乱有的编号还没有显示这是为什么呢我们主观认为应该是打印出来0-9编号的线程啊这怎么打印的这么乱呢 其实这里就涉及到线程调度的话题了创建出来的多个新线程以及主线程谁先运行这是不确定的这完全取决于调度器我们事先无法预知哪个线程先运行所以就有可能出现新线程一直没有被调度主线程一直被调度的情况也有可能主线程的for循环执行到i等于6或9或8的时候新线程又被调度起来了此时新线程内部就会打印出创建成功的语句。所以打印的结果很乱这也非常正常因为哪个线程先被调度是不确定的 线程的终止和等待三种终止方式 pthread_join()的void**retval 再谈完线程的创建之后那什么时候线程终止呢所以接下来我们要谈论的就是线程终止的话题线程终止总共有三种方式分别为returnpthread_exitpthread_cancel 我们知道线程在创建的时候会执行对应的start_routine函数指针指向的方法所以最正常的线程终止方式就是等待线程执行完对应的方法之后线程自动就会退出如果你想要提前终止线程可以通过最常见的return的方式来实现线程函数的返回值为void*一般情况下如果不关心线程退出的情况直接return nullptr即可。 和进程终止类似的是除return这种方式外原生线程库还提供了pthread_exit接口来终止线程接口的使用方式也非常简单只要传递一个指针即可同样如果你不关心线程的退出结果那么也只需要传递nullptr即可。 #include iostream #include string #includeunistd.h #includevector #include stdio.h #includefunctional #include time.h #include pthread.h#define NUM 10 using namespace std; // using func_t functionvoid(); typedef functionvoid() func_t;class ThreadData { public:ThreadData(const std::string name, const time_t ctime, func_t f):_name(name), _createtime(ctime), _func_t(f){}public:string _name;time_t _createtime;func_t _func_t; };void Print() {std::cout 我是线程执行的大任务的一部分 std::endl; }void* start_routine(void* arg) {ThreadData* td static_castThreadData* (arg);cout I am a new thread, my name is : td-_name creatname is: td-_createtime endl; td-_func_t();//return nullptr; //线程终止pthread_exit(nullptr); }int main() {//创建一批线程for(int i 0; i NUM; i){pthread_t tid;char threadname[64];snprintf(threadname, sizeof(threadname), %s: %d, thread , i1);//创建一个线程数据对象string tdname threadname;ThreadData* td new ThreadData(tdname, (time_t)time(nullptr), Print);pthread_create(tid, nullptr, start_routine, td);sleep(1);}return 0; }谈完上面两种线程终止的话题后第三种终止方式我们先等会儿再说与进程类似进程退出之后要被等待也就是回收进程的资源否则会出现僵尸进程僵尸的这种状态可以通过ps指令axj选项看到同时会产生内存泄露的问题。 线程终止同样也需要被等待但线程这里没有僵尸线程这样的概念如果不等待线程同样也会造成资源泄露也就是PCB资源未被回收线程退出的状态我们是无法看到的我们只能看到进程的Z状态。 原生线程库给我们提供了对应的等待线程的接口其中join的第二个参数是一个输出型参数在join的内部会拿到线程函数的返回值然后将返回值的内容写到这个输出型参数指向的变量里面也就是写到我们用户定义的ret指针变量里通过这样的方式来拿到线程函数的返回值。 通过bash的打印结果就可以看到每个线程都正常的等待成功了。 #include iostream #include string #includeunistd.h #includevector #include stdio.h #includefunctional #include time.h #include pthread.h#define NUM 5 using namespace std; // using func_t functionvoid(); typedef functionvoid() func_t;class ThreadData { public:ThreadData(const std::string name, const time_t ctime, func_t f):_name(name), _createtime(ctime), _func_t(f){}public:string _name;time_t _createtime;func_t _func_t; };void Print() {std::cout 我是线程执行的大任务的一部分 std::endl; }void* start_routine(void* arg) {ThreadData* td static_castThreadData* (arg);cout I am a new thread, my name is : td-_name creatname is: td-_createtime endl; td-_func_t();//return nullptr; //线程终止//pthread_exit(nullptr);return (void*)110; }int main() {vectorpthread_t tids;//保存线程的tid//创建一批线程for(int i 0; i NUM; i){pthread_t tid;char threadname[64];snprintf(threadname, sizeof(threadname), %s: %d, thread , i1);//创建一个线程数据对象string tdname threadname;ThreadData* td new ThreadData(tdname, (time_t)time(nullptr), Print);pthread_create(tid, nullptr, start_routine, td);tids.push_back(tid);sleep(1);}void* retval nullptr;for(int i 0; i NUM; i){//线程的等待pthread_join(tids[i], retval);cout join sucess, retval is: ;cout (long long)retval endl;sleep(1);}return 0; }在了解join拿到线程函数的返回值之后我们再来谈最后一个线程终止的方式pthread_cancel叫做线程取消。首先线程要被取消前提一定得是这个线程是跑起来的跑起来的过程中我们可以选择取消这个线程换个说法就是中断这个线程的运行。 如果新线程是被别的线程取消的话则新线程的返回值是一个宏PTHREAD_CANCELED这个宏其实就是把-1强转成指针类型了所以如果我们join被取消的线程那join到的返回值就应该是-1如果线程是正常运行结束退出的话默认的返回值是0. 我们让创建出来的每个新线程跑10s然后在第5s的时候主线程取消前5个线程那么这5个线程就会被中断主线程阻塞式的join就会提前等待到这5个被取消的线程并打印出线程函数的返回值发现结果就是-1再经过5s之后其余的5个线程会正常的退出主线程的join会相应的等待到这5个线程并打印出默认为0的退出结果。 #include iostream #include string #include unistd.h #include vector #include stdio.h #include functional #include time.h #include pthread.h#define NUM 10 using namespace std; // using func_t functionvoid(); typedef functionvoid() func_t;class ThreadData { public:ThreadData(const std::string name, const time_t ctime, func_t f): _name(name), _createtime(ctime), _func_t(f){}public:string _name;time_t _createtime;func_t _func_t; };void Print() {std::cout 我是线程执行的大任务的一部分 std::endl; }void *start_routine(void *arg) {ThreadData *td static_castThreadData *(arg);int cnt 10;while (cnt--){cout I am a new thread, my name is : td-_name creatname is: td-_createtime endl;td-_func_t();// return nullptr; //线程终止// pthread_exit(nullptr);// return (void*)110;sleep(1);} }int main() {vectorpthread_t tids; // 保存线程的tid// 创建一批线程for (int i 0; i NUM; i){pthread_t tid;char threadname[64];snprintf(threadname, sizeof(threadname), %s: %d, thread, i 1);// 创建一个线程数据对象string tdname threadname;ThreadData *td new ThreadData(tdname, (time_t)time(nullptr), Print);pthread_create(tid, nullptr, start_routine, td);tids.push_back(tid);//sleep(1);}sleep(5);for (int i 0; i NUM / 2; i){pthread_cancel(tids[i]);cout cancel: tids[i] success endl;}void *retval nullptr;for (int i 0; i NUM; i){// 线程的等待pthread_join(tids[i], retval);cout join sucess, retval is: ;cout (long long)retval endl;//sleep(1);}return 0; }
http://www.zqtcl.cn/news/913037/

相关文章:

  • 做淘客网站用备案网络推广预算方案
  • 网站建设需不需要招标好网站欣赏
  • 怎样创建网站的代码此网站域名即将过期
  • 网页转向网站jquery图片效果网站
  • 山东定制网页建站wordpress是是什么技术
  • 无锡免费网站制作手游网页版
  • 东莞 网站建设 定制水寻找常州微信网站建设
  • 在门户网站做推广网站开发需要20万
  • 网站做电商销售需要注册吗上海的公司地址
  • 给网站做选题计算机网络技术电商网站建设与运营方向
  • 网站如何做熊掌号并绑定wordpress pdf
  • wordpress页面构建器中文文山seo公司
  • 凡科免费做网站蜂箱尺寸与制作图片
  • 完全不收费的聊天软件班级优化大师下载安装app
  • 合肥网站改版360免费建站永久免费
  • 商业网站建设案例课程 下载工信部企业网站认证
  • 泉州网站设计哪家公司好沈阳seo代理计费
  • 做景观素材有哪几个网站国内建网站费用
  • 驻马店重点项目建设网站wordpress常规选项
  • 网站开发 英文网站策划建设阶段的推广
  • 建立网站一般多少钱wordpress评论跳过验证
  • 南京每月做社保明细在哪个网站查看设计作品的网站软件
  • html怎么做网站如何在腾讯云上网站建设
  • 网站建设怎么链接表格手机做外贸有什么好的网站
  • 深圳开发网站建设哪家好外贸网络营销培训
  • 广州智迅网络做网站免费下载ps素材网站
  • 什么网站时候做伪静态开发软件定制
  • 找人做网站 多少钱西宁市公司网站建设
  • 网页设计 教程网站找权重高的网站方法
  • 网站建设本地还是外地重庆seo排名方法