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

陕西建设工程合同备案网站百度一下你就知道主页

陕西建设工程合同备案网站,百度一下你就知道主页,国外怎么做直播网站吗,wordpress做css目录 一 前言 二 线程控制 1. POSIX线程库(原生线程库) 2. 创建线程 2.1 pthread_create 2.2pthread_self()获取线程id 3.线程终止 3.1.return 方式 3.2 pthread_exit 4 线程等待 三 理解线程tid 一 前言 在上一篇文章中我们已经学习了线程的概念,线程的创…

目录

一 前言

二 线程控制

1. POSIX线程库(原生线程库)

2. 创建线程

2.1 pthread_create

 2.2pthread_self()获取线程id

 3.线程终止

3.1.return 方式

3.2 pthread_exit 

 4 线程等待

三 理解线程tid 


一 前言

   在上一篇文章中我们已经学习了线程的概念,线程的创建,并且已经从根本上了解了线程和进程的相同点及不同点。在学习进程时,我们学习了进程的相关概念,进程控制接口,而线程作为更轻量级的进程,其自然也有着控制接口。 


二 线程控制

1. POSIX线程库(原生线程库)

  • 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”打头的
  • 要使用这些函数库,要通过引入头文 件 <pthread.h>
  • 链接这些线程函数库时要使用编译器命令的“-lpthread”选项

2. 创建线程

2.1 pthread_create

功能:创建一个新的线程

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void * (*start_routine)(void*), void *arg);

  1. 参数 thread:返回线程ID
  2. attr:设置线程的属性,attr为NULL表示使用默认属性
  3. start_routine:是个函数地址,线程启动后要执行的函数
  4. arg:传给线程启动函数的参数
  5. 返回值:成功返回0;失败返回错误

上一章节我们是创建了一个线程,接下来我们创建多个线程

#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <cstdio>using namespace std;void* start_routine(void* args )
{string name=static_cast<const char*>(args);//安全类型转换while(true){cout<<"new thread create success, name: "<<name<<endl;sleep(1);}
}int main()
{//1.创建一批线程vector<pthread_t> tids;#define NUM 10for(int i=0;i<NUM;i++){pthread_t tid;char namebuffer[64];snprintf(namebuffer,sizeof namebuffer,"%s: %d","thread",i);//为每个线程设置编号// pthread_t id;//一旦创建成功,就执行上面的执行流pthread_create(&tid,nullptr,start_routine,(void*)namebuffer);}// //2.主执行流while(true){   cout<<"new thread create success, name: main thread"<<endl;sleep(1);}

 测试结果

🍉:从测试结果我们观察到和我们预想的结果不一样,接下来我们用下图解释

接下来我们对代码进行一定修改 

 void* start_routine(void* args )
{sleep(1);ThreadData* td =static_cast<ThreadData*>(args);//安全类型转换int cnt=10;while(cnt){cout<<"new thread create success, name: "<<td->namebuffer<<"cnt: "<<cnt--<<endl;sleep(1);}delete td;return nullptr;
}int main()
{//1.创建一批线程vector<ThreadData*> threads;#define NUM 10for(int i=0;i<NUM;i++){
/在这里我们通过new一个对象//ThreadData* td=new ThreadData();
///snprintf(td->namebuffer,sizeof (td->namebuffer),"%s: %d","thread",i+1);//为每个线程设置编号// pthread_t id;//一旦创建成功,就执行上面的执行流
///这里我们将地址td传给pthread_create/pthread_create(&(td->tid),nullptr,start_routine,td);
保证了每一个执行流有自己独立的new对象/threads.push_back(td);sleep(1);}}

🚢:start_routine这个函数现在被十个线程执行,这个函数现在 是重入状态

这个函数是可重入函数吗?答案是的,因为这个函数并没有产生二义性。在函数内部定义的变量叫局部变量,具有临时性。每个线程都有自己独立的栈结构


 2.2pthread_self()获取线程id

 该接口的作用是:获取调用此接口的线程的id,并将id作为返回值。 


 3.线程终止

3.1.return 方式

exit() 能不能用来终止线程呢?答案是不能的,因为exit是终止进程的,任何一个执行流调用exit()都会让整个进程退出。 接下来我们引入一个接口,用来终止线程。

3.2 pthread_exit 

🙂:我们在讲到进程退出的时候,退出是有退出码和退出信号的,为什么在线程这里线程退出的返回值是void 什么都没有呢?

因为线程异常退出,也就是进程退出,所以退出信号是进程该关心的事。  

 4 线程等待

线程也是要被等待的,如果不等待,会造成类似僵尸进程的问题----------内存泄漏

线程等待:

1. 获取线程的退出信息

2.回收新线程对应的PCB等内核资源,防止内存泄漏。

 pthread_join 接口

  for(auto& iter:threads)//遍历threads{   //等待线程int n=pthread_join(iter->tid,nullptr);assert(n==0);cout<<"join: "<<iter->namebuffer<<"success"<<endl;delete iter;}cout<<"main thread quit"<<endl;

测试结果

  接下来我们对pthread_join(pthread_t thread, void **retval)第二个参数进行一下说明。

 

接下来我们对代码做个简单改变,让大家明白第二个参数的使用,pthread _join(pthread_tthread,void** retval)函数是如何获取线程函数的返回结果的。

void* start_routine(void* args )
{ThreadData* td =static_cast<ThreadData*>(args);//安全类型转换int cnt=10;while(cnt){// cout<<"cnt: "<<cnt <<"&cnt"<< &cnt<<endl;// cnt--;// sleep(1);cout<<"new thread create success, name: "<<td->namebuffer<<"cnt: "<<cnt--<<endl;sleep(1);}// delete td;
*******************这是我们的改动return (void*)2;//我们让每个线程函数返回2
}
 for(auto& iter:threads)//遍历threads{//我们想要获取线程函数void*类型的返回结果,要设置一个void*变量void* ret=nullptr;//通过取地址&ret,来取到这个返回结果,所以为什么pthread_join()//第二个参数是void** 类型的,因为其是个输出线参数。int n=pthread_join(iter->tid,&ret);assert(n==0);cout<<"join: "<<iter->namebuffer<<"success: "<<(long long)ret<<endl;delete iter;}

运行结果 

线程控制

创建线程-------->>>>>线程结束----------------->>>>>线程等待


 我们知道对于线程我们为了回收资源不造成内存泄漏,默认情况下都是要进行join的,但是对于我们需要关心线程返回值的情况,必须使用pthread_join()接口函数。如果我们并不关心该线程的返回值,那么其实我们可以不用手动回收线程,可以让其系统自动回收,这就是线程分离 

pthread_detach()

该接口的作用是 将线程与主线程分离,主线程就不管该分离线程的返回值、退出和资源回收情况 。这个接口一般是线程自己调用或者主线程调用


三 理解线程tid 

我们在Linux: 线程概念初识-CSDN博客中说过  int n= pthread_create(&tid,nullptr,thread_routine,(void*)"thread_one");tid是个输出型参数,这个tid的值并不是LWP的值。接下来我们就要对线程的id进行说明,为什么其是一个地址。

🚀:我们在线程概念初识这章节讲过,每个线程都有自己独立的栈结构,这个时候我们会有个疑问?无论有多少个线程,严格来说都在一个进程中,而一个进程有一份程序地址空间,也就是说只有一个栈结构,那么为什么说线程都有自己独立的栈结构呢?

http://www.dtcms.com/wzjs/510069.html

相关文章:

  • 网站开发与维护总结广东seo教程
  • 绵阳网站开发公司无锡营销型网站建设
  • 中铁建设集团有限公司网站专业seo站长工具全面查询网站
  • 淘客怎么做网站推广网络运营培训班多少钱
  • 制作公司网站源代码怎么弄阿里指数数据分析平台
  • 协会网站建设的优势培训师资格证怎么考
  • 企业做网站还是做平台好百度搜索风云榜小说
  • 网站怎么做响应免费引流推广
  • 怎样学做网站运营关键词推广效果分析
  • 湖南中维电力建设有限公司网站软文推广做得比较好的推广平台
  • 大连市城乡建设委员会网站导购网站怎么推广
  • 网站建设及推广方案ppt如何创建自己的网站平台
  • 属于b2b电子商务网站网站keywords
  • 做旅游网站有前途吗凡科网
  • 用HBuilder做网站的模板百度平台我的订单
  • 中国城乡住房建设厅网站需要优化的网站有哪些?
  • 免费背景图片素材网站快速网站轻松排名
  • 免费企业网站制作seo代码优化工具
  • 网站开发与硬件合同文大侠seo博客
  • 百姓网站外推广怎么做郴州seo网络优化
  • 济南专业网站建设咨询营销型网站建设需要多少钱
  • 建德做网站点击器原理
  • 课程网站怎么做3d建模培训班一般多少钱
  • 真人做爰视频网站免费下载怎么创建网站快捷方式
  • 网站做二维码百度惠生活推广怎么收费
  • 网站后台使用怎么在百度上做公司网页
  • 山西自助建站费用低国家域名注册服务网
  • 网站上线之前做测试吗郴州网站seo外包
  • 网站建设使用哪种语言好aso优化教程
  • 一品威客做的网站好用吗深圳seo教程