一步一步写线程之十六线程的安全退出之一理论分析

一、多线程的开发

多线程的开发,在实际场景中几乎是无法避开的。即使是前端看似没有使用线程,其实在底层的框架中也使用了线程进行了支撑。至少到现在,不管是协程还是其它什么新的编程方式,仍然无法撼动线程的主流地位。
多线程的开发中,各种复杂的场景今天不分析,只分析一种场景,就是多线程的退出,或者说整体程序的安全退出。有过开发经验的可能都遇到过,程序运行的很好,但一退出就崩溃了。甚至还有的遇到过,有些程序无法退出,只能使用一些特殊的手段暴力杀死线程才能退出。这些现象的出现,其实基本上都是多线程的协调机制(同步、通信等)没有做好。
下面就对多线程的安全退出进行分析和说明。

二、线程的运行分析

既然要线程安全的退出,就必须明白线程在运行时的工作环境。知己知彼,百战不殆。下面就分析一下涉及到线程退出时的一些重点:
1、上下文
线程在执行时,会有一些上下文环境,在操作系统里称为context,其中的内容有很多,但其实重点就是堆栈和一些存储的值,这些值包括一些文件句柄和内存等的值。这为线程的恢复提供了依据,如果上下文被破坏,可想而知结果会是什么。
2、资源
线程运行的目的就是了处理各种任务,任务中包括本身分配的资源和系统分配的资源。而多线程之所以被使用,目的就是为了处理任务及任务相关的数据,这些数据大多数的情况下是依赖和被 依赖于其它线程的(一般只有在学习时才会写一些独立的线程逻辑,与其它线程无关)。而这些数据和资源可能要和其它线程共享,也有可能返回给其它线程,甚至有可能让其它线程来负责销毁和回收。
这就出现了一个很明显的问题,如何在退出时保证资源和数据已经完整正确的发出。如果强行退出,外送的数据不正确,(包括不一致,未发送,发送错误等很多情况)会不会产生问题。举一个例子,一个数据库存储的字段,需要A线程处理,然后送给B线程再加工,然后由C线程负责存储,如果其中一个线程意外退出,那么C线程要么无数据可存储,要么是数据有问题。
同样,如果某种情况,程序退出时出现了问题,产生了僵尸进程。那么它就会占用一系列的系统的资源。同样,非安全退出导致一些系统资源未释放,如硬件IO(端口、句柄等)中的相关资源。那么,此时二次启动时程序可能就无法再次安全启动。
3、协调
多线程的开发,一般来说必然会带来线程间的协调调度,这才是多线程复杂的原因。正如很早前就分析的,如果多个线程只是自己搞自己的事情,和其它线程都没关系,那么这不是真正的多线程开发,从某种意义上来讲,它就是单线程开发。
既然涉及到协调,就有一个问题,某个线程的退出以另外一个线程设置某项条件才能退出,如果设置条件的线程意外退出,整个程序可能就无法退出。通常这也是常见的一种多线程退出的问题。
另外,多线程间的同步如果处理不好,则有可能在退出时造成死锁。同样,也可能因为线程退出的无序,导致资源和内存的泄露等等。所以,多线程的退出就是打仗一样,“进攻是很复杂的,但是撤退更复杂,撤退搞不好就会演变成为溃败!”
明白了吧,万物都是相通,就是这个道理。

三、安全退出的机制和方法

明白了多线程在运行时的情况,那么就可以有针对性的处理这些情况,从而保证多线程退出时的安全。下面就上面分析的几个方面提出几个解决思路:
1、等待机制
通过让线程睡眠或者其它的Wait(一般都有超时机制),等待所有的线程完成后,再共同退出。这种方法简单、粗暴,但对一些新手或者说应用场景简单的情况下,不失为一种解决办法。缺点就是延迟太大,可能在某些情况下仍无法正常退出。
2、轮询机制
就是设立一个标志位或者标记状态,由各个线程去反复的查询,如果到达退出的状态,即可退出。这种方法相对简单,但浪费资源且有较大的退出延迟,一般也是在简单或者特定的场景下使用。
3、消息机制
消息机制是通过多线程间消息的有序传递,来保证线程间有序的安全退出。这种方法相对来说更安全也更优雅。但其实现要相对复杂一些,而且不同的OS中消息机制都有所不同,需要开发者要有针对性的去开发。
4、事件机制
事件机制类似于消息机制,同样也很安全。其缺点与消息机制大致相同。另外,如果开发者考虑不足,还有可能陷入死循环或死锁。
针对这些思路,就有了更具体的解决办法:
1、不同的系统与库中对线程的处理有所不同,以标准库和Linux为例,它的线程创建有两种处理方式,一种是deatch方式,一种是join方式。两种方式的处理机制不同,前者主线程退出子线程也就安全的退出而后者则需要等待子线程的退出后整体程序才会退出。不同的机制有着不同的处理方式,这就看实际场景了,如果实际应用子线程中的数据没有什么意义或者对其它线程没什么影响,就可以使用前者。否则就需要使用后者。
而如果使用后者,就需要参考上面的解决思路,使用类sleep,固定量的死循环等等;或者设置状态位(原子变量或普通变量)不断轮询;或者Linux下的信号如SIGINT、SIGTERM等,Windows可以使用WM开头的系列消息;更优雅的可以使用信号量、条件变量、Windows下的Event机制等等。
2、资源的处理
不管是句柄还是内存亦或什么其它资源,简单一些还好说,一般不会有什么问题。但是多了后如何处理?首推当然是RAII,就是为了解决这类问题的。如果不想使用RAII,也可以利用损害集中管理原则,将资源的处理交到指定的对象中,集中处理。

四、总结

其实多线程如此,多进程大抵亦也如此!只不过目前来看写多进程的已经非常少了。总结到最后,多线程的安全退出只有一条原则,就是让每个线程自己正常退出,而不是暴力打断它的执行。只要贯彻了这一原则,就不会出现多线程退出的各种异常问题。
可是,实际的场景复杂又多变,有的时候确实无法等待所有的线程正常的退出,这就需要开发者自己根据情况进行取舍。有舍才有得,亘古不变的道理!

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

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

相关文章

ISAAC SIM踩坑记录--添加第三方3D场景

ISAAC SIM仿真首先就是要有合适的3D场景,官方提供了一些场景,如果不能满足要求,那就只能自己建。 对于我这种不会3D建模的菜鸟,只能到网上下载了,sketchfab就是一个不错的平台,有不少免费资源可以下载。 …

人工智能_大模型091_大模型工作流001_使用工作流的原因_处理复杂问题_多轮自我反思优化ReAct_COT思维链---人工智能工作笔记0236

# 清理环境信息,与上课内容无关 import os os.environ["LANGCHAIN_PROJECT"] "" os.environ["LANGCHAIN_API_KEY"] "" os.environ["LANGCHAIN_ENDPOINT"] "" os.environ["LANGCHAIN_TRACING_V…

完全按照手册win10里装Ubuntu 虚拟机然后编译ESP32(主要是想针对ESP32C3和S3)开发板的鸿蒙系统(失败)

基本上完全按照手册来的,除了Ubuntu虚拟机使用了22.04 Jammy版本,鸿蒙手册里是20.04 版本,主要是鸿蒙里3年前的手册了,所以就擅自用了高版本。 据此还想到一点,鸿蒙LiteOS,还挺稳定的,3年也没有…

一文理解多模态大语言模型——下

作者:Sebastian Raschka 博士, 翻译:张晶,Linux Fundation APAC Open Source Evangelist 编者按:本文并不是逐字逐句翻译,而是以更有利于中文读者理解的目标,做了删减、重构和意译&#xff0c…

【Leetcode Top 100 - 扩展】328. 奇偶链表

问题背景 给定单链表的头节点 h e a d head head,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。 第一个 节点的索引被认为是 奇数 , 第二个 节点的索引为 偶数 ,以此类推。 请注意&#xf…

使用伪装IP地址和MAC地址进行Nmap扫描

使用伪装IP地址和MAC地址进行Nmap扫描 在某些网络设置中,攻击者可以使用伪装的IP地址甚至伪装的MAC地址进行系统扫描。这种扫描方式只有在可以保证捕获响应的情况下才有意义。如果从某个随机的网络尝试使用伪装的IP地址进行扫描,很可能无法接收到任何响…

k8s 之 Role-Based Access Control

在 Kubernetes 中,RBAC(Role-Based Access Control)是一个用来控制对 Kubernetes 资源访问的授权机制。它通过定义不同角色(Role)和这些角色可以访问的权限,确保只有被授权的用户或服务能够执行特定的操作。…

什么是TCP的三次握手?

TCP的三次握手:深入理解建立可靠连接的过程 引言 在计算机网络中,传输控制协议(TCP)是确保数据可靠传输的核心协议之一。TCP通过三次握手机制来建立一个稳定的、双向的连接,这对于确保数据的完整性和顺序至关重要。本…

SpringBoot该怎么使用Neo4j - 优化篇

文章目录 前言实体工具使用 前言 上一篇中,我们的Cypher都用的是字符串,字符串拼接简单,但存在写错的风险,对于一些比较懒的开发者,甚至觉得之间写字符串还更自在快速,也确实,但如果在后期需要…

MySQL中on和where的区别

select name, bonus from Employee left join Bonus on Employee.EmpId Bonus.EmpId where bonus is null or bonus < 1000 作者&#xff1a;力扣官方题解 链接&#xff1a;https://leetcode.cn/problems/employee-bonus/ 来源&#xff1a;力扣&#xff08;LeetCode&#x…

数据科学与大数据之间的区别

什么是数据科学&#xff1f; 数据科学是一个跨学科领域&#xff0c;它将统计学和计算方法相结合&#xff0c;旨在从数据中提取见解和知识。它涉及收集、处理、分析以及解读数据&#xff0c;以揭示可用于为决策过程提供依据并推动创新的模式、趋势和关系。 数据科学涵盖了广泛…

neo4j如何存储关于liquidity structure的层次和关联结构

在 Neo4j 中存储关于流动性结构&#xff08;liquidity structure&#xff09;的层次和关联结构非常适合&#xff0c;因为 Neo4j 是一个基于图的数据库&#xff0c;能够自然地建模和存储复杂的关系和层次结构。下面是如何在 Neo4j 中设计和实现这样的数据模型的详细步骤和示例。…

七牛云成功保存但无法显示和访问{“error“:“download token not specified“}

在使用七牛云存储图片时&#xff0c;前端通过链接访问图片时遇到错误&#xff1a; {"error":"download token not specified"} 具体表现为&#xff1a; 后端通过 access_key 和 secret_key 生成了上传和下载的 Token。前端将域名与 res.key 拼接后生成图…

智慧银行反欺诈大数据管控平台方案(四)

智慧银行反欺诈大数据管控平台的核心内容&#xff0c;是通过整合多维度、多层次的金融交易信息&#xff0c;利用先进的大数据分析、机器学习与人工智能算法&#xff0c;构建一个系统性、实时性和智能化的反欺诈管控网络&#xff0c;旨在提供全面、高效、精准的风险评估机制。该…

jmeter基础_打开1个jmeter脚本(.jmx文件)

课程大纲 方法1.菜单栏“打开” 菜单栏“文件” - “打开” &#xff08;或快捷键&#xff0c;mac为“⌘ O”&#xff09;&#xff0c;打开文件选择窗口 - 选择脚本文件&#xff0c;点击“open”&#xff0c;即可打开脚本。 方法2.工具栏“打开”图标 工具栏点击“打开”图标&…

TCP编程案例

笔记&#xff1a;&#xff08;本题可能需要的&#xff09; TCP协议&#xff1a; TCP协议进行通信的两个应用进程&#xff1a;客户端、服务端。 使用TCP协议前&#xff0c;须先建立TCP连接&#xff0c;形成基于字节流的传输数据通道 传输前&#xff0c;采用“三次握手”方式…

静态链接的特点 ;动态链接的特点

1) 静态链接的特点 静态链接&#xff08;Static Linking&#xff09;是在程序编译时&#xff0c;将程序中使用的所有库函数和代码直接复制到最终生成的可执行文件中。其特点包括&#xff1a; 独立可执行文件&#xff1a;生成的可执行文件包含了程序运行所需的所有代码和数据&…

STM32 BootLoader 刷新项目 (十三) Python上位机介绍

STM32 BootLoader 刷新项目 (十三) Python上位机介绍 大家好&#xff0c;这是我们STM32 BootLoader的最后一篇文章了&#xff0c;讲述用Python写的上位机&#xff0c;也更新了半年时间了&#xff0c;谢谢大家的支持&#xff0c;到目前为止&#xff0c;已经更新了12篇文章了&am…

Kronecker Sum

文章目录 1. kronecker sumpython 代码 1. kronecker sum A [ 6 8 1 4 ] ; B [ 5 3 7 6 ] ; \begin{equation} A\begin{bmatrix}6&8\\\\1&4\end{bmatrix};B\begin{bmatrix}5&3\\\\7&6\end{bmatrix}; \end{equation} A ​61​84​ ​;B ​57​36​ ​;​​ k…

ArUco识别定位原理

1. ArUco是什么 ArUco marker是一种汉明码方格图。它由一个宽的黑边和一个内部的二进制矩阵组成&#xff0c;黑色的边界有利于快速检测到图像&#xff0c;Marker ID是他的二进制矩阵编码&#xff0c;Marker size是图片的大小。黑色方块对应0&#xff0c;白色方块对应1&#xf…