Liunx:线程控制

       

目录

创建线程:pthread_create();

线程等待:pthread_join();

线程退出:pthread_exit();

线程取消:pthread_cancel()


        说线程的时候说过,liunx没有选择单独定义线程的数据结构和适配算法,而是用轻量级进程来实现线程,有人将轻量级进程的系统调用进行了封装,在应用层实现了线程的相关功能,目前大部分的liunx平台都默认安装了第三方库,pthread.h。

        创建线程:pthread_create();

        man 一下该函数可以出现相关介绍:

        pthread_t *thread,输出型参数,一个进程可以创建多个线程,为了方便控制,该参数返回线程的id。这个是你在该函数之前需要定义的一个变量,pthread_t是一个长整型。 

     const pthread_attr_t *attr,用来设置创建线程时的属性,一般我们传递一个空指针,线程的属性使用系统默认的就可以。

        void *(*start_routine) (void *),函数指针,该函数返回值是void*,参数是void*。我们暂时把它叫做功能函数。

        void *arg,第三个参数传递了一个函数,这个参数将来会传给你的功能函数做参数。

        线程创建成功返回0,线程创建失败以返回值的形式返回错误码。

#include <iostream>
#include <pthread.h>
#include <unistd.h>using namespace std;void *Function(void *arg)
{while (true){cout << "new thread: " << getpid() << endl<< endl;sleep(2);}
}int main()
{pthread_t pid = 0;int err = pthread_create(&pid, nullptr, Function, nullptr);if (err == 0){cout << " create thread successfully!  " << endl;}while (true){cout << "main thread: " << getpid() << endl<< endl;sleep(1);}return 0;
}

        上面的代码演示了怎么创建一个线程,运行:


        ldd 可以查看你的程序链接了哪些库:

        查看进程也能看到只有一个mythread:

        从这也能说明,一个进程可以有多个线程,多个线程只是一个进程不同的执行流。

        但是查看线程的话,你可以明显看到这两个执行流:
 

        LWP,light weight process id,轻量级进程id。PID=LWP的线程就是主线程,也就是程序运行最先创建的PCB。

        当你任意的干掉一个线程,整个进程也会被干掉:

        

        我们kill 的不是主线程,而是进程中的一个新线程,进程中的任意一个线程崩溃都会导致整个进程的崩溃。专业点说,多线程较单线程,程序的健壮性降低。

        还要说一下创建线程成功后的第一个参数的值,用%p格式打印::

        tid不等于LWP,实际上是一个地址,至于为什么,稍后说。


线程等待:pthread_join();

        要等待某个线程,第一个参数就是创建该线程时的tid,第二个参数是用来取出你传入的功能函数的返回值。

        等待成功返回0,失败返回错误码。

        

void *Function(void *arg)
{int cnt=5;while (cnt--){cout << "new thread: " << getpid() << endl<< endl;sleep(1);}
}int main()
{pthread_t pid = 0;int err = pthread_create(&pid, nullptr, Function, nullptr);if (err == 0){cout << " create thread successfully!  " << endl;}int err_join=pthread_join(pid,nullptr);if(err_join==0){cout<<" new thread wait successfully! main thread exit....."<<endl;}return 0;
}

        运行:

        主线程在等待新线程5秒运行完成后才退出,默认是阻塞等待。如果主线程比新线程先退出,会造成类似于僵尸进程的情况,也就是新线程的创建的一些资源无法回收,造成内存泄露的问题。

        然后再说第二个参数。我们要知道一个函数的执行情况是根据函数的返回值,假如说我们没法在应用层接收功能函数的返回值,请问你如何知道函数的执行情况?或者你说可以通过错误码,但是一个进程只有一个错误码,可你有多个线程。其次我们无法捕捉到线程的异常,线程异常后整个进程都退出了,程序崩溃之后你只能知道有异常,至于哪个线程抛出的,没有办法捕捉。还有就是我们不主要用这个参数来查看线程的执行情况,他还有其他用途,后面说。在说为什么是一个二级指针。

        我们的功能函数返回一个void*值,这个值在应用层,我们就假设功能函数执行完成的返回值返回到了pthread_join()函数里,你想要拿到一个函数内部的void*类型的值,那你的输出型参数就应该是void** retval,在函数内部进行复制*retval(void*)=void* ;这样类型就匹配了。这样用:

线程退出:pthread_exit();

        线程退出你直接可以用return,也可以用这个,哪个线程调用这个函数,哪个线程就退出。

线程取消:pthread_cancel()

        在主线程里不等新线程运行结束就直接取消。

        


int main()
{pthread_t tid = 0;int err = pthread_create(&pid, nullptr, Function, nullptr);if (err == 0){cout << " create thread successfully!  " << endl;}sleep(1);//等待一秒确保线程创建成功pthread_cancel(tid);void* retval=nullptr;pthread_join(tid,&retval);cout<<" new thread wait successfully! "<<"exit:"<<(long long int)retval<<"main thread exit....."<<endl;   return 0;
}​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/413213.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件测试|深入了解Python中的super()函数用法

简介 Python中的super()函数是一种强大的工具&#xff0c;用于在子类中调用父类的方法。它在面向对象编程中非常有用&#xff0c;可以让你轻松地扩展和重用现有的类。本文将详细介绍super()函数的用法&#xff0c;并提供一些示例来帮助你更好地理解它的功能。 什么是super()函…

el-date-picker如果超过限制跨度则提示

需求&#xff1a;实现日期时间选择组件跨度如果超过限制天数&#xff0c;点击查询则提示超过限制时间 封装一个方法&#xff0c;传入开始和结束时间以及限制天数&#xff0c;如果超过则返回false //计算时间跨度是否超过限制天数isTimeSpanWithinLimit(startTime, endTime, li…

Firefox 100 正式发布

五月三日&#xff0c;Firefox发布了它的第100个版本&#xff0c;来回顾一下Firefox是如何走到今天这一步的&#xff0c;以及在第100个版本中发布了哪些功能。 回顾 2004年&#xff0c;《纽约时报》上宣布了Firefox 1.0的发布&#xff0c;这个广告列出了为第一版做出贡献的每一…

Seaborn可视化的各种图及代码演示

一.简介 Seaborn是基于matplotlib的图形可视化python包。它提供了一种高度交互式界面&#xff0c;便于用户能够做出各种有吸引力的统计图表。 Seaborn是在matplotlib的基础上进行了更高级的API封装&#xff0c;从而使得作图更加容易&#xff0c;在大多数情况下使用seaborn能做…

Modbus协议学习第三篇之协议通信规则

导语 本篇博客将深入介绍Modbus协议的一些内容&#xff0c;主要包括通讯方式和通讯模型的介绍 Modbus通讯方式 Modbus协议是单主机、多从机的通信协议&#xff0c;即同一时间&#xff0c;总线上只能有一个主设备&#xff0c;但可以有一个或者多个从设备&#xff08;最多好像是2…

SpringMVC下半篇之异常处理器及日期转换器

3.异常处理器 如果不加以异常处理&#xff0c;错误信息肯定会抛在浏览器页面上&#xff0c;这样很不友好&#xff0c;所以必须进行异常处理。 3.1.异常处理思路 系统的dao、service、controller出现都通过throws Exception向上抛出&#xff0c;最后由springmvc前端控制器交由…

图像处理中,采用极线约束准则来约束特征点匹配搜索空间,理论上在极线上进行搜索。这里的极线是什么线,怎么定义的?基本矩阵F和本质矩阵E有什么区别?

问题描述&#xff1a;图像处理中&#xff0c;采用极线约束准则来约束特征点匹配搜索空间&#xff0c;理论上在极线上进行搜索。这里的极线是什么线&#xff0c;怎么定义的&#xff1f;基本矩阵F和本质矩阵E有什么区别&#xff1f; 问题1解答&#xff1a; 极线是通过极线几何学…

银行家算法

文章目录 主要内容一.银行家算法1.需求分析 2.概要设计3.源代码代码如下&#xff08;示例&#xff09;: 总结 主要内容 一.银行家算法 1.需求分析 通过编写和调试一个系统动态分配资源的简单模拟程序&#xff0c;观察死锁产生条件&#xff0c;采用适当的算法&#xff0c;有效…

Discuz论坛网站登录账号操作慢,必须强制刷新才会显示登录怎么办?

飞飞发现在登录服务器大本营账号时&#xff0c;输入账号密码登录后还是显示的登录框&#xff0c;强制刷新后才知道已经登录了&#xff0c;每次都要刷新才能正常显示&#xff0c;非常影响用户体验&#xff0c;于是在网上找了类似的问题故障解决方法&#xff0c;目前问题已经解决…

移动端开发进阶之蓝牙通讯(四)

移动端开发进阶之蓝牙通讯(四) 在移动端开发实践中,可能会要求在不同的设备之间切换,从而提升用户体验; 或者为了提升设备的利用率,实现设备之间的连接和协同工作; 不得不通过多端连接,将多个设备连接在一起,实现设备之间的数据共享、远程控制等功能,根据具体的应用…

黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(6)解散部门

指路&#xff08;1&#xff09;&#xff08;2&#xff09;&#xff08;3&#xff09;&#xff08;4&#xff09;&#xff08;5&#xff09;&#x1f447; 黑马程序员JavaWeb开发|案例&#xff1a;tlias智能学习辅助系统&#xff08;1&#xff09;准备工作、部门管理_tlias智能…

Elasticsearch:和 LIamaIndex 的集成

LlamaIndex 是一个数据框架&#xff0c;供 LLM 应用程序摄取、构建和访问私有或特定领域的数据。 LlamaIndex 是开源的&#xff0c;可用于构建各种应用程序。 在 GitHub 上查看该项目。 安装 在 Docker 上设置 Elasticsearch 使用以下 docker 命令启动单节点 Elasticsearch 实…