进程的控制

news2024/11/22 14:22:49

在这里插入图片描述

文章目录

  • 1. Linux线程创建和等待
  • 2. 线程ID
  • 3. 线程的局部存储
  • 4. 分离线程

1. Linux线程创建和等待

在这里插入图片描述
这是前面写过的创建线程的代码,现在我们把线程的ID打印看一下:
在这里插入图片描述
我们可以看到线程的id特别大,这是为什么呢?我们后面再说。

如果我们想自己获取自己的线程ID,该怎么办呢
在这里插入图片描述
那么谁调用了这个函数,就获取谁的线程ID。

在这里插入图片描述
这里我们可以先写个打印函数,哪个线程对应的线程id我们打印出来。
在这里插入图片描述
运行结果如下:
在这里插入图片描述
可以看到每个线程的id不相同。

那么创建一个线程后我们也必须等待,不然可能会造成内存泄漏:
在这里插入图片描述

如果线程异常的该怎么办呢
在这里插入图片描述
我们在这个线程5秒之后出现异常,来看运行情况:
在这里插入图片描述
线程异常会导致整个进程异常,线程会影响到其它线程,它的健壮性降低。

pthread_join的第二个参数value_ptr的意义是什么
它是一个输出型参数,获取新线程退出时的退出码
1. 线程退出的方式,return
在这里插入图片描述因为返回值是void*的,所以我们需要先强转。
在这里插入图片描述
在打印ret,我们也需要强转成long long,不然会出现段错误。

运行结果如下:
在这里插入图片描述
从运行结果可以看出:可以成功获取线程的退出码。

我们知道:进程退出有3种方式,1.代码跑完,结果正确。2.代码跑完,结果不正确。3.异常退出。

但是线程退出不需要异常,因为线程异常等于进程异常。以后我们只考虑线程正常终止

2. 线程退出的方式,pthread_exit
在这里插入图片描述
在这里插入图片描述
3. 线程退出的方式,pthread_cancel
在这里插入图片描述
这里是获取线程的id来退出。

在这里插入图片描述
首先,我们让新线程死循环。
在这里插入图片描述
让主线程去取消新线程。
在这里插入图片描述
从运行结果我们可以看到:新线程也成功退出了。

为什么结果是-1呢
因为线程退出,是OS帮我们做的。它会帮我们在线程的task_struct里面修改对应的退出码

4. 线程退出的方式,以new的方式
在这里插入图片描述
我们把new出来的地址返回。
在这里插入图片描述
我们也可以在外面销毁空间。

运行结果如下:
在这里插入图片描述

2. 线程ID

从上面的结果我们可以看出线程的ID特别大,那么线程的ID到底是什么呢
它其实就是一个地址!我们知道:线程是一个独立的执行流,并且线程一定会在自己的运行过程中,产生临时数据(调用函数,定义局部变量等)

线程一定需要有自己的独立的栈结构
下面就谈一谈线程栈:
在这里插入图片描述
这里我们使用的线程库是用户级线程库,它是动态链接。

它的链接过程如下:
在这里插入图片描述
首先,我们先把自己的线程加载到物理内存,然后通过页表映射到代码区去执行。当我们执行到pthread_creat这种库函数时,发现没有,就会从磁盘中加载到物理内存,然后通过页表映射到共享区。
在这里插入图片描述
此时线程就会从代码区转到共享区。
在这里插入图片描述
在共享区执行完成后,再转到我们的代码区。

在代码区中,我们的自己的代码,调用库的代码,系统调用的代码,所有代码的执行都是在进程的地址空间当中执行的

下面我们来看一下库和OS的关系:
在这里插入图片描述
线程的全部实现,并没有全部体现在OS内,而是OS提供的执行流,具体的线程结构由库来进行管理

既然需要管理,库就会创建相关的结构体:struct thread_info,里面存了线程id和私有栈等等。那么库就会在共享区把我们的结构体信息的虚拟起始地址返回,所以pthread_t对应的就是用户级线程的控制结构体的起始地址。

Linux中,线程库用户级线程库,和内核的LWP是1:1关系

主线程的独立栈结构,用的就是地址空间中的栈区。新线程用的栈结构,用的是库中提供的栈结构

3. 线程的局部存储

下面讲解一个概念,线程的局部存储是什么
我们知道:我们定义的全局变量是默认被全部线程共享的,如果我们想让某个全局变量变成私有,我们就需要定义线程的局部存储

那么我们该如何定义
在这里插入图片描述
我们把每个线程的global_val的值和地址都打印出来,并且设置一个变量看它的变化。

运行结果如下:
在这里插入图片描述
可以看出:每个线程的global_val的地址都是一样的,并且每个执行流都对同一个global_val进行++。

如果我们想让这个全局变量变成每个线程的私有,我们可以这样:
在这里插入图片描述
在变量前面加上__thread(记住是两个_)。
在这里插入图片描述
每个线程的global_val的地址都不一样了,并且只对自己的++。

我们知道:每个线程id在内核中都有对应的轻量级进程LWP,这个线程的id是给我们用户自己用的,我们不需要用LWP,如果我们就想要LWP,我们就需要绕过这个pthread线程库。
在这里插入图片描述
我们需要调用这个系统调用,但是这个我们不能直接调用,直接调用会出错。
在这里插入图片描述
我们需要用这个系统调用。
在这里插入图片描述
运行结果:
在这里插入图片描述

4. 分离线程

默认情况下,新创建的线程是joinable的(意思是可以等待的),线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏。
pthread_join的作用是:1。释放线程资源,前提是线程退出了。2.获取线程对应的退出码

如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。
在这里插入图片描述
可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离:
在这里插入图片描述
joinable和分离是冲突的,一个线程不能既是joinable又是分离的

举个例子:
在这里插入图片描述
我们在每个自己的线程里给自己分离了。
在这里插入图片描述
然后我们把等待退出码再打印出来看一下。

运行结果如下:
在这里插入图片描述
我们可以看到线程分离后,线程还是在运行。
在这里插入图片描述
我们在这里加一个sleep看一下:
在这里插入图片描述
我们可以看到,出现错误了。

这是为什么呢
首先,我们要知道:CPU调度线程的运行是不确定的,一开始的情况是CPU先调度了主线程,然后去调度新线程,也就是说主线程先阻塞等待了,新线程还没来的及分离。
所以,我们更倾向于让主线程,分离其他线程

新线程分离,如果主线程先退出,那么进程就退出,新线程也就退出了。一般我们分离线程,对应的main thread一般不要退出(常驻内存的进程)

如何理解exit
在这里插入图片描述
我们在线程里面exit,看一下运行情况:
在这里插入图片描述
任何一个线程调用exit,都表示整个进程退出

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文简介Spring的IOC和AOP

1、IOC 概念:所谓控制反转,就是把原先我们代码里面需要实现的对象创建、依赖的代码,反转给容器来帮忙实现。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。 …

飞桨AI Day落地澳门高校!助力大湾区打造产教融合新范式

为了推动大湾区建设产教融合的人工智能技术生态,加快培养助力社会经济高质量发展的复合型 AI 人才,飞桨校园 AI Day 登陆澳门,开展《AI 技术发展趋势与人才培养》主题讲座 ,邀请多位澳门科技大学及百度嘉宾,解读当下AI…

【中兴ZXV10 B860A1.1】

这里写自定义目录标题 开启adb开启adb 部分盒子的ADB调试位置,在设置页面中可以有开启开发者选项。地区界面不同,位置不同有的在设置里。 如果找不到,直接按住遥控器【返回】不放,5秒后,快速不停按【左键】。 点击【打开ADB调试】这时侯让你输入密码 下载zikaikeji.ap…

chatgpt赋能python:Python如何创建集合——你必须知道的所有知识

Python 如何创建集合——你必须知道的所有知识 作为一位有10年 Python 编程经验的工程师,我可以告诉你,Python 集合是编程中非常重要的一部分。如果你不知道如何创建集合,那么你可能会错过很多东西。所以,让我们深入探讨 Python …

提供一个使用Npoi生成excel文档的例子,应能帮助到各位使用Npoi的朋友,因为具有多种情形处理

提供一个使用Npoi生成excel文档的例子,应能帮助到各位使用Npoi的朋友,因为具有多种情形处理 照例,文章开始之前,先看下最终效果: 实现的需求点如下: 1.第一行大标题加了背景色,且这个背景色&…

解密 JS 参数:逆向工程的实用技巧

大家好,我是安果! 大部分网站都会对关键参数进行加密,JS 逆向时,我们首要任务是定位参数具体的加密逻辑 常见方式包含:关键字搜索、堆栈调试、XHR 及事件监听、AST 内存漫游、JS Hook 注入等 本篇文章以 JS Hook 注入定…

惊爆!Python打造花式照片墙!

大家注意:因为微信最近又改了推送机制,经常有小伙伴说错过了之前被删的文章,比如前阵子冒着风险写的爬虫,再比如一些限时福利,错过了就是错过了。 所以建议大家加个星标,就能第一时间收到推送。&#x1f44…

NXP IMX8M + Ethercat+Codesys工业实时运动控制解决方案

面向边缘计算应用的全新i.MX 8M Plus异构应用处理器,搭载专用神经网络加速器、独立实时子系统、双摄像头ISP、高性能DSP和GPU。 恩智浦半导体宣布推出i.MX 8M Plus应用处理器,进一步丰富其业界领先的产品组合。这是恩智浦首个集成了专用神经处理引擎&…

G0第25章:Gin框架进阶项目实战

1 Gin框架源码解析 通过阅读gin框架的源码来探究gin框架路由与中间件的秘密。 1.1 Gin框架路由详解 gin框架使用的是定制版本的httprouter,其路由的原理是大量使用公共前缀的树结构,它基本上是一个紧凑的Trie tree 或者只是(Radix Tree&am…

Linux Tomcat服务 虚拟主机 多实例部署

Tomcat 服务 Tomcat 是 Java 语言开发的,Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器。Tomcat 属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 java开发的JSP 动态页面程序的首选。一般…

Linux教程——常见Linux发行版本有哪些?

新手往往会被 Linux 众多的发行版本搞得一头雾水,我们首先来解释一下这个问题。 从技术上来说,李纳斯•托瓦兹开发的 Linux 只是一个内核。内核指的是一个提供设备驱动、文件系统、进程管理、网络通信等功能的系统软件,内核并不是一套完整的…

DDD领域模型

一、分层介绍 controller层:处理页面或者api请求的输入输出,定义VO(REQ,RES),没有业务逻辑,只做请求处理和下层逻辑接application层:处理跨领域domain的复杂逻辑,定义DTOdomain层:领域核心逻辑…

深入理解Qt多线程编程:QThread、QTimer与QAudioOutput的内在联系__QObject的主线程的事件循环

深入理解Qt多线程编程:QThread、QTimer与QAudioOutput的内在联系__QObject的主线程的事件循环 1. Qt多线程编程的基础1.1 QObject和线程(QObject and Threads)1.2 QThread的使用和理解(Understanding and Using QThread&#xff0…

C#,码海拾贝(35)——求“实对称矩阵““特征值与特征向量“的“雅可比法“之C#源代码

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 矩阵类 /// 作者&#xff1a;周长发 /// 改进&#xff1a;深度混淆 /// https://blog.csdn.net/beijinghorn /// </summary> public partial class Matrix {…

编码器 | 基于 Transformers 的编码器-解码器模型

基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶。本文简要介绍了神经编码器-解码器模型的历史&#xff0c;更多背景知识&#xff0c;建议读者阅读由 Sebastion Ruder 撰写的这篇精彩 博文。此外&#xff0c;建议读者对 自注意力 (…

【AUTOSAR】Bootloader说明(一)---- 时序流程

电机控制器选用TI TMS28xx DSP&#xff0c;包括boot-loader与应用软件两个部分。其中boot-loader包括下列内容&#xff1a; RAM自检应用程序有效性检查UDS命令处理FLASH操作 下面分别说明DSP上电后整个软件运行流程及程序刷新过程。 DSP软件执行流程 DSP复位后&#xff0c;将…

【Mysql基础】-关于常用的函数简单案例

目录 一、系统函数 二、日期函数 三、字符串函数数 说明&#xff1a;以下所有的操作在8.0的mysql数据库操作系统上操作 一、系统函数 1 显示连接列表&#xff1a;show PROCESSLIST; 2 MD5加密&#xff1a;select MD5("root") 二、日期函数 1、 推算一周之后的…

QMI8658 - 姿态传感的零偏(常值零偏)标定

1. 零偏 理论上在静止状态下三轴输出为0,0,0&#xff0c;但实际上输出有一个小的偏置&#xff0c;这是零偏的静态分量&#xff08;也称固定零偏&#xff09;。 陀螺生产出来后就一直固定不变的零偏值。对于传统的高性能惯性器件来说&#xff0c;该误差在出厂标定时往往就被补偿…

《水经注地图服务》用户如何登录?

《水经注地图服务》&#xff08;WeServer&#xff09;是一款可快速发布全国乃至全球海量卫星影像的地图发布服务产品&#xff0c;该产品完全遵循OGC相关协议标准&#xff0c;是一个基于若干项目成功经验总结的产品。它可以轻松发布100TB级海量卫星影像&#xff0c;从而使“在内…

如何使用 Raycast 一键打开预设工作环境

工作中&#xff0c;你一定遇到过这样的场景&#xff1a;你正在认真写代码&#xff0c;线上突然出现报警。看到报警信息之后&#xff0c;你不得不打开浏览器&#xff0c;点开收藏夹&#xff0c;打开监控页面、告警页面、trace 页面、日志搜索平台……有时&#xff0c;还需要打开…