Linux多线程(四)之Linux线程控制2【线程等待和线程终止】

article/2025/9/6 9:40:01

文章目录

      • 线程等待
      • 线程终止
        • return退出线程
        • pthread_exit退出线程
        • pthread_cancel取消线程

线程等待

哪个线程先运行?由调度器说的算。

但是主线程一定要是最后退出!

为什么需要线程等待?

  1. 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。(内存泄漏)
  2. 创建新的线程不会复用刚才退出线程的地址空间。
  3. 关心线程运行的结果数据!(获取线程的执行情况)

image-20250428221448210

功能:等待线程结束
原型int pthread_join(pthread_t thread, void **value_ptr);
参数thread:线程IDvalue_ptr:它指向一个指针,后者指向线程的返回值
返回值:成功返回0;失败返回错误码

调用该函数的线程将挂起等待,直到id为thread的线程终止。

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}return nullptr;//在这里默认线程就退出了
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");pthread_join(tid,nullptr);//主线程等待默认阻塞等待!cout<<"main thread quit!!"<<endl;return 0;
}

image-20250428222058610

thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,

总结如下:

  1. 如果thread线程通过return返回,

    value_ ptr所指向的单元里存放的是thread线程函数的返回值。

  2. 如果thread线程被别的线程调用pthread_ cancel异常终掉,

    value_ ptr所指向的单元里存放的是常数PTHREAD_ CANCELED

  3. 如果thread线程是自己调用pthread_exit终止的,

    value_ptr所指向的单元存放的是传给pthread_exit的参数。

  4. 如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数。

image-20250425230912326

获取返回值的原理

image-20250428224330738

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}return (void*)1;//在这里默认线程就退出了
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");void*ret;pthread_join(tid,&ret);//主线程等待默认阻塞等待!cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;//注意不能用int,因为int4字节	void*8字节return 0;
}

image-20250428224928206

在线程join的时候不考虑异常是因为线程出异常了,整个进程都会终止!

线程终止

主线程退出了那么整个进程就退出了!

如果需要只终止某个线程而不终止整个进程,可以有三种方法:

  1. 从线程函数return

    这种方法对主线程不适用,从main函数return相当于调用exit

  2. 线程可以调用pthread_ exit终止自己。

  3. 一个线程可以调用pthread_ cancel终止同一进程中的另一个线程。

*pthread_exit*函数

image-20250428230734514

功能:线程终止
原型void pthread_exit(void *value_ptr);
参数value_ptr:value_ptr不要指向一个局部变量。
返回值:无返回值,跟进程一样,线程结束的时候无法返回到它的调用者(自身)

需要注意

pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,

不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。

*pthread_cancel*函数

image-20250428230814140

功能:取消一个执行中的线程
原型int pthread_cancel(pthread_t thread);
参数thread:线程ID
返回值:成功返回0; 失败返回错误码

exit可以退出线程吗?

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <cstdlib>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}exit(11);
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");void*ret;pthread_join(tid,&ret);//主线程等待默认阻塞等待!cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;return 0;
}

image-20250428230438047

很明显把整个进程都终止了!

所以exit是用来终止进程的,不能用来终止线程!

return退出线程
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}return (void*)1;//在这里默认线程就退出了
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");void*ret;pthread_join(tid,&ret);cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;return 0;
}

image-20250428224928206

pthread_exit退出线程
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <cstdlib>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}pthread_exit((void*)100);
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");void*ret;pthread_join(tid,&ret);cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;return 0;
}

image-20250428231055339

pthread_cancel取消线程
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <cstdlib>using namespace std;void *threadroutine(void *args)
{const char *name = (const char *)args;int cnt=0;while (1){cout << name << ": " << getpid() << endl;sleep(1);cnt++;if(cnt==5){break;}}pthread_exit((void*)100);
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadroutine, (void *)"Thread 1");sleep(1);//只是为了保证新线程已经启动pthread_cancel(tid);void*ret;pthread_join(tid,&ret);//主线程等待默认阻塞等待!cout<<"main thread quit!!ret: "<<(long long int)ret<<endl;return 0;
}

image-20250428231751379


http://www.hkcw.cn/article/wMyCUbpaVP.shtml

相关文章

Python自动化之selenium语句——浏览器设置显示尺寸、截图、刷新网页

目录 一、浏览器设置最大化、最小化 1.浏览器最大化 2.浏览器最小化 二、浏览器打开的位置、尺寸 1.浏览器打开位置 2.浏览器打开尺寸 三、浏览器截图 1.截图语句 2.运行成功后查看 四、刷新网页 上一节实现了打开浏览器、打开指定网址、关闭浏览器的操作&#xff0c…

Selenium的第三天打卡——Selenium应用(selenium元素选取以及浏览器操作)

Selenium 4 应用示例解析 目录 Selenium 4 应用示例解析 一、基本配置 二、浏览器设置&#xff08;这之前没有html基础的朋友可以先去了解一下html哦&#xff09; 三、元素定位方法 1.Selenium 4 元素的选中 ①开发者模式 ②观察代码 2.Selenium 4 元素抓取的核心内容…

智能仓储落地:机器人如何通过自动化减少仓库操作失误?

仓库作业的速度和准确性至关重要&#xff0c;尤其是在当前对无差错、高效作业的要求达到前所未有的环境下。每一个错误&#xff0c;无论是物品放错位置还是库存差异&#xff0c;都会在供应链中产生连锁反应&#xff0c;造成延误、增加成本&#xff0c;并最终影响客户满意度。 …

【Linux系统移植】Cortex-A8 Linux系统移植(超详细)

目录 前言 一、ARM开发板ARM简介RISC和CISCARM产品分布核心板S5pv210 SOC嵌入式系统开发方式 二、嵌入式系统组成为什么要系统移植内核移植框图 三、嵌入式开发环境搭建搭建开发环境总流程设置ubuntu与windows共享目录修改用户为root用户安装NFS服务器安装tftp服务器安装交叉编…

如何通过数据分析优化项目决策

通过数据分析优化项目决策需从明确数据分析目标、选择适当的数据分析工具、确保数据质量、建立数据驱动文化等方面入手&#xff0c;其中&#xff0c;明确数据分析目标是优化决策过程的基础&#xff0c;只有清晰明确的数据分析目标才能指导有效的数据采集与分析&#xff0c;避免…

纯前端实现图片伪3D视差效果

作者&#xff1a;vivo 互联网前端团队- Su Ning 本文通过depth-anything获取图片的深度图&#xff0c;同时基于pixi.js&#xff0c;通过着色器编程&#xff0c;实现了通过深度图驱动的伪3D效果。该方案支持鼠标/手势与手机陀螺仪双模式交互&#xff0c;在保证性能的同时&#x…

在ROS2(humble)+Gazebo+rqt下,实时显示仿真无人机的相机图像

文章目录 前言一、版本检查检查ROS2版本 二、步骤1.下载对应版本的PX4(1)检查PX4版本(2)修改文件名(3)下载正确的PX4版本 2.下载对应版本的Gazebo(1)检查Gazebo版本(2)卸载不正确的Gazebo版本(3)下载正确的Gazebo版本 3.安装bridge包4.启动 总结 前言 在ROS2的环境下&#xff…

Git的三种合并方式

在 Gitee&#xff08;码云&#xff09;中合并分支主要有三种方式&#xff1a;​普通合并&#xff08;Merge Commit&#xff09;、压缩合并&#xff08;Squash Merge&#xff09;​和变基合并&#xff08;Rebase Merge&#xff09;​。每种方式适用于不同的场景&#xff0c;各有…

微机系统-汇编语言入门

汇编语言及其程序设计 -1:汇编语言的语句格式 [名字] 操作符 操作数&#xff1b; [注释] 名字: 1. 是一种标识符。 2. 组成&#xff1a;A&#xff5e;Z&#xff0c;a&#xff5e;z&#xff1b; 0&#xff5e;9&#xff1b; 专用符号 &#xff1f;&#xff0e; _$ 3. 限制&…

互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景

一&#xff1a;并发 1.1MySQL并发事务访问相同记录 &#xff08;1&#xff09;读-读 不影响 &#xff08;2&#xff09;写-写 写的数据需要一个一个来&#xff0c;排队执行 &#xff08;3&#xff09;读-写 两次读…

影楼精修-AI追色算法解析

注意&#xff1a;本文样例图片为了避免侵权&#xff0c;均使用AIGC生成&#xff1b; AI追色是像素蛋糕软件中比较受欢迎的一个功能点&#xff0c;本文将针对AI追色来解析一下大概的技术原理。 功能分析 AI追色实际上可以理解为颜色迁移的一种变体或者叫做升级版&#xff0c;…

MATLAB中的table数据类型:高效数据管理的利器

MATLAB中的table数据类型&#xff1a;高效数据管理的利器 什么是table数据类型&#xff1f; MATLAB中的table是一种用于存储列向数据的数据类型&#xff0c;它将不同类型的数据组织在一个表格结构中&#xff0c;类似于电子表格或数据库表。自R2013b版本引入以来&#xff0c;t…

nacos服务注册

Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c;在国内受欢迎程度较高。 1. 服务注册到nacos Nacos是SpringCloudAlibaba的组件&#xff0c;而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此…

【FPGA开发】Ubuntu16.04环境下配置Vivado2018.3—附软件包

文章目录 环境介绍关键步骤记录安装虚拟机及镜像安装vivadolicense导入 环境介绍 vivado&#xff1a;2018.3 虚拟机&#xff1a;vmware 16 pro 镜像&#xff1a;Ubuntu16.04 64位 所有相关软件压缩包&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/fd2730b46b20 提取码…

安全帽检测算法AI智能分析网关V4守护工地/矿山/工厂等多场景作业安全

一、方案概述​ 在工业生产与建筑施工场景中&#xff0c;安全帽是保障人员安全的重要装备。但传统人工巡检效率低、易疏漏&#xff0c;难以满足现代安全管理需求。AI智能分析网关V4安全帽检测方案&#xff0c;借助人工智能与计算机视觉技术&#xff0c;实现作业现场安全帽佩戴…

【计算机网络】第2章:应用层—应用层协议原理

目录 1. 网络应用的体系结构 2. 客户-服务器&#xff08;C/S&#xff09;体系结构 3. 对等体&#xff08;P2P&#xff09;体系结构 4. C/S 和 P2P 体系结构的混合体 Napster 即时通信 5. 进程通信 6. 分布式进程通信需要解决的问题 7. 问题1&#xff1a;对进程进行编址…

Baklib云内容中台构建实践

云端资产整合实践 在数字化转型进程中&#xff0c;企业通常面临多系统数据孤岛与内容管理低效的挑战。Baklib云内容中台通过微服务架构设计&#xff0c;实现了跨平台文档、音视频及结构化数据的统一纳管&#xff0c;支持将分散在本地服务器、第三方云存储及业务系统中的数字资…

SOC-ESP32S3部分:17-I2C驱动实例-EEPROM温湿度传感器

飞书文档https://x509p6c8to.feishu.cn/wiki/KrlCwmlKcikvZ5knxEbcrewwn1c EEPROM 特别说明&#xff0c;目前ESP32S3由于IO数量少的原因&#xff0c;是没有连接底板的EEPROM的&#xff0c;我们这里只进行代码讲解&#xff0c;这个工程不能在板卡运行的。 我们学习基础课程时…

局域网内文件共享的实用软件推荐

软件介绍 在日常办公、学习或家庭网络环境里&#xff0c;局域网内文件共享是个常见需求。有一款免费的局域网共享软件非常适合这种场景。 这款局域网共享软件使用起来非常简单&#xff0c;不需要安装&#xff0c;直接点击就能使用。 软件下载 链接&#xff1a;​​https://p…

华为OD机试真题——AI面板识别(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…