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

苏州专业网站建设东莞谷歌推广公司

苏州专业网站建设,东莞谷歌推广公司,商用自适应网站建设,网站中文字内容左右切换的js代码目录 pthread_create -- 创建线程 参数 返回值 代码 -- 不传 args: 编译时带 -lpthread 运行结果 为什么输出混杂? 如何证明两个线程属于同一个进程? 如何证明是两个执行流? 什么是LWP? 代码 -- 传 args&a…

目录

pthread_create -- 创建线程

参数

返回值

 代码 -- 不传 args:

编译时带  -lpthread

运行结果 

为什么输出混杂?

如何证明两个线程属于同一个进程?

 

如何证明是两个执行流? 

什么是LWP?

代码 -- 传 args:

运行结果:

pthread_self -- 线程标识符

代码:

LWP标识符 和 线程标识符的区别

pthread_join -- 等待线程退出

 前言:主线程比新线程先退出

参数

返回值

 代码 -- 不获取退出状态

代码 -- 获取退出状态

 ​编辑

pthread_exit -- 终止线程

前言:新、主线程共享地址空间

参数

作用

代码 

pthread_cancel -- 取消线程

参数

返回值

代码


pthread_create -- 创建线程

#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

参数

thread: 指向一个 pthread_t 类型的指针,用于存储新创建线程的标识符,是输出型参数

attr: 指向一个 pthread_attr_t 类型的指针,这个参数可以用来设置线程的属性,如栈大小、调度策略等。如果不需要特别设置线程属性,可以传递 NULL

start_routine: 这是一个函数指针,指向新线程开始执行的函数。该函数必须接受一个 void* 类型的参数,并返回一个 void* 类型的结果。

arg: 这个参数将被传递给 start_routine 函数作为其唯一的参数。如果你不想传递任何参数,可以使用 NULL

返回值

如果函数调用成功,返回值为 0

如果发生错误,返回值为一个非零的错误代码

 代码 -- 不传 args:

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;void* newthreadRun(void* args)
{while(1){cout<<"I am new thread"<<endl;sleep(1);}
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,nullptr);while(1){cout<<"I am main thread"<<endl;sleep(1);}return 0;
}

编译时带  -lpthread

这里需要了解一点小故事,用户知道线程和进程,但不知道轻量级进程,而Linux中没有真线程,Linux中没有线程相关的系统调用,只有轻量级进程的系统调用,为了让用户和系统达成一致,系统将轻量级进程的系统调用进行封装,转换成线程相关的接口语义提供给用户,也就有了pthread库(即原生线程库),这个库既不属于C语言,也不属于C++,所以在Linux系统中编写多线程时,都必须在编译时带上 -lpthread。

在 Linux 中编译使用 Pthreads 的程序时,通常需要链接 Pthreads 库。这可以通过编译命令中添加 -lpthread 选项来实现。-lpthread 选项不仅告诉编译器链接 Pthreads 库,还会启用一些必要的编译器选项,以确保线程支持的正确性和性能。 如果不使用 -lpthread 选项,编译器可能会报错或生成不可用的二进制文件。

thread:thread.ccg++ -o $@ $^ -std=c++11 -lpthread.PHONY:clean
clean:rm -f thread

运行结果 

可以看出,两个执行流同时输出信息。同时也可以看出,一开始新、主线程打印的消息混在一起了,后面才分开来,这是正常现象。

为什么输出混杂?

在多线程程序中,多个线程同时向终端输出信息时,可能会出现输出混杂的情况。这是因为每个线程的输出操作并不是原子的(原子操作,即要么完全执行,要么根本不执行),即一个线程可能在另一个线程已经开始输出但还没有完成输出时就开始了自己的输出,这种现象通常称为“输出交错”或“输出混杂”。 

如何证明两个线程属于同一个进程?

不传 args 版本的代码运行时,输入命令 ps ajx | head -1 && ps ajx | grep thread 筛选出 thread 进程,可以看出只有一个进程被调度

如何证明是两个执行流? 

当代码运行起来时,输入命令 ps -aL | head -1 && ps -aL | grep thread 可以查看线程的信息,可以看出两个线程的 pid 一样,即属于同一个进程,而 LWP 不同,则说明一个进程中有两个执行流

ps -aL-a显示所有进程,包括其他用户的进程,-L 显示每个线程的详细信息。 

什么是LWP?

LWP(Light Weight Process)是轻量级进程的缩写,在 Linux 中,LWP 通常被称为“线程”

代码 -- 传 args:

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;while(cnt--){std::cout<<threadname<<" is running: "<<cnt<<", pid: "<<getpid()<<" mythread id: "<<toHex(pthread_self())<<std::endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,(void*)"thread-1");pthread_join(tid,nullptr);return 0;
}

运行结果:

pthread_self -- 线程标识符

#include <pthread.h>
pthread_t pthread_self(void);

该函数用于获取当前线程的标识符pthread_t 类型)。

代码:

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{while(1){cout<<"I am new thread, new thread tid: "<<toHex(pthread_self())<<", pid: "<<getpid()<<endl;sleep(1);}
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,nullptr);while(1){cout<<"I am main thread, main thread tid: "<<toHex(pthread_self())<<", pid: "<<getpid()<<endl;sleep(1);}return 0;
}

可以看出,新、主线程的线程标识符 tid 的值不一样,同时也可以看出,LWP 和线程标识符 tid的值是不一样的

LWP标识符 和 线程标识符的区别

 LWP(Light Weight Process)标识符和线程标识符(Thread Identifier,TID)在数值上通常是不一样的。虽然它们在概念上密切相关,但它们表示的是不同的标识符,用途和获取方式也有所不同。

pthread_join -- 等待线程退出

 前言:主线程比新线程先退出

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;//新线程运行5秒while(cnt--){std::cout<<threadname<<" is running: "<<cnt<<", pid: "<<getpid()<<" mythread id: "<<toHex(pthread_self())<<std::endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,(void*)"thread-1");sleep(1);//因为主线程没有阻塞等待新线程,1秒后,主线程先退出了std::cout<<"main thread quit"<<std::endl;return 0;
}

因为主线程没有阻塞等待新线程退出,1秒后,主线程退出了,主线程退出了就等同于整个进程退出了,分配给进程的资源都被释放了,所以所有的线程都要退出,所以新线程还没执行完就被退出了,通常需要主线程最后结束。线程的退出也需要wait,不然会发生内存泄漏问题。


#include <pthread.h>int pthread_join(pthread_t thread, void **value_ptr);

该函数用于等待指定的线程终止,并获取该线程的退出状态。 

参数

thread:要等待的线程的标识符pthread_t 类型,可以调用 pthread_self 函数获取)。

value_ptr输出型参数,用于存储线程的退出状态。如果不需要获取退出状态,可以传递 NULL

返回值

等待线程退出成功返回 0。 

等待线程退出失败返回非零错误码

 代码 -- 不获取退出状态

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;while(cnt--){std::cout<<threadname<<" is running: "<<cnt<<", pid: "<<getpid()<<" mythread id: "<<toHex(pthread_self())<<std::endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,(void*)"thread-1");int n=pthread_join(tid,nullptr);//获取返回值std::cout<<"main thread quit, n="<<n<<std::endl;return 0;
}

新线程正常退出,故返回值为 0. 

代码 -- 获取退出状态

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;while(cnt--){std::cout<<threadname<<" is running: "<<cnt<<", pid: "<<getpid()<<" mythread id: "<<toHex(pthread_self())<<std::endl;sleep(1);}return (void*)123;
}
int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,(void*)"thread-1");void* ret=nullptr;int n=pthread_join(tid,&ret);//ret强转为long long是为了避免精度损失std::cout<<"main thread quit, n="<<n<<",main thread get a ret:"<<(long long)ret<<std::endl;return 0;
}

线程的退出状态其实就是线程执行的任务函数的返回值。 

 

pthread_exit -- 终止线程

前言:新、主线程共享地址空间

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>
int g_val=100;
string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;while(cnt--){printf("new thread, g_val:%d,&g_val:%p\n",g_val,&g_val);g_val++;//在新线程中改变g_val的值sleep(1);}return nullptr;
}int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,(void*)"thread-1");int cnt=10;while(cnt--){//主线程不改变g_val的值printf("main thread, g_val:%d,&g_val:%p\n",g_val,&g_val);sleep(1);}void* ret=nullptr;int n=pthread_join(tid,&ret);std::cout<<"main thread quit, n="<<n<<",main thread get a ret:"<<(long long)ret<<std::endl;return 0;
}

可以看出,新线程修改了 g_val 的值,主线程中 g_val 的值也被修改了,说明新、主线程共享了地址空间,看到的是同一个变量,而不是和进程一样,发生写时拷贝。

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>
int g_val=100;
string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;while(cnt--){printf("new thread, g_val:%d,&g_val:%p\n",g_val,&g_val);g_val++;//故意对空指针进行解引用int *p=nullptr;*p=10;sleep(1);}return nullptr;
}int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,(void*)"thread-1");int cnt=10;while(cnt--){printf("main thread, g_val:%d,&g_val:%p\n",g_val,&g_val);sleep(1);}void* ret=nullptr;int n=pthread_join(tid,&ret);std::cout<<"main thread quit, n="<<n<<",main thread get a ret:"<<(long long)ret<<std::endl;return 0;
}

 

在新线程中故意对野指针进行解引用,结果新、主线程一起退出了,这是因为在同一个进程中运行的所有线程共享相同的地址空间,这意味着如果一个线程造成了段错误(segmentation fault),那么这个错误会影响到整个进程,而不仅仅是单个线程。操作系统通常会终止整个进程以防止进一步的损坏


#include <pthread.h>void pthread_exit(void *value_ptr);

参数

value_ptr:一个指向指针的指针,用于存储线程的退出状态

这个值可以被 pthread_join 函数捕获并使用。如果不需要传递退出状态,可以传递 NULL

作用

终止当前线程:调用 pthread_exit 的线程会立即终止其执行

传递退出状态:可以通过 value_ptr 参数传递一个退出状态,这个状态可以被 pthread_join 函数捕获。

代码 

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>
int g_val=100;
string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;while(cnt--){printf("new thread, g_val:%d,&g_val:%p\n",g_val,&g_val);g_val++;sleep(1);}pthread_exit((void*)123);
}int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,(void*)"thread-1");void* ret=nullptr;int n=pthread_join(tid,&ret);std::cout<<"main thread quit, n="<<n<<",main thread get a ret:"<<(long long)ret<<std::endl;return 0;
}

pthread_cancel -- 取消线程

#include <pthread.h>int pthread_cancel(pthread_t thread);

参数

thread:要取消的线程的标识符pthread_t 类型)。

返回值

取消线程成功,返回 0

取消线程失败,返回非零错误码

代码

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>
int g_val=100;
string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),"0x%lx",tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;while(cnt--){printf("new thread, g_val:%d,&g_val:%p\n",g_val,&g_val);g_val++;sleep(1);}pthread_exit((void*)123);
}int main()
{pthread_t tid;pthread_create(&tid,nullptr,newthreadRun,(void*)"thread-1");pthread_cancel(tid);void* ret=nullptr;int n=pthread_join(tid,&ret);std::cout<<"main thread quit, n="<<n<<",main thread get a ret:"<<(long long)ret<<std::endl;return 0;
}

线程的退出状态为 -1,表示线程被取消。

http://www.rdtb.cn/news/20969.html

相关文章:

  • 鹤壁市网站建设重庆seo薪酬水平
  • wordpress高级培训seo百度百科
  • 商贸有限公司英文seo哪个软件好
  • 彩票游戏网站开发网站运营策划书范文
  • 文创设计网站郑州seo优化外包热狗网
  • 网站建设合伙人百度知道登录
  • 网站备案信息抽查武汉大学人民医院地址
  • 邯郸做网络推广的公司搜索引擎排名优化是什么意思
  • 长沙网站优化方案怎么建自己的网站?
  • 禅城网站建设广告营销
  • 国内外网站建设长沙seo管理
  • 网站对于企业的好处怎样进行seo
  • 有哪些推广的网站外链发布软件
  • 外链 推网站怎么做营销型网站的分类
  • o2o与网站建设海门网站建设
  • 果洛wap网站建设多少钱公众号推广接单平台
  • 建设一个聊天类的网站关键词排名提高方法
  • 500套wordpress模板合肥全网优化
  • 电商网站建设论文百度扫一扫入口
  • 网上做任务赚钱网站福州seo快速排名软件
  • 网站排名套餐百度24小时人工客服电话
  • 厦门建设网站制作网站流量排名
  • asp.net 网站开发 pdf餐饮营销引流都有什么方法
  • 无备案网站广告如何做b站推广是什么意思
  • 临安市建设局网站湖南正规关键词优化报价
  • cn域名有名的网站网络推广关键词优化公司
  • 网站开发工具以及优缺点营销网站建设创意
  • 郑州网站建设招聘软文推广代写代发
  • 宜昌网站seo收费商品热搜词排行榜
  • 北京企业网站建设飞沐厦门seo推广外包