Linux 线程安全 (1)

news2024/12/23 13:16:11

文章目录

  • 线程互斥概念
  • 互斥实际使用
  • 互斥锁的原理
  • 死锁问题说明

线程互斥概念

  1. 执行流

执行流是指操作系统对进程或线程的调度和执行顺序。它决定了程序中的指令按照何种顺序被执行。
现阶段可以粗浅的理解为,执行流决定执行哪个线程或进程的代码(或者说执行流决定了CPU资源的分配),执行流执行代码的顺序逻辑即为程序员编写代码时的顺序逻辑。 一台主机上会有多个进程或线程时,实际上不是一个进程或线程分配到一个执行流(执行流的数量取决于CPU的核心数量), 而是执行流不挺的根据预先设置好的执行流调度算法(即CPU资源分配算法)在各个进程或线程之间切换,由于切换的速度很快、CPU的计算速度很快(对人来说)以及CPU调度算法的作用,用户往往干受不到这个过程。

  1. 可重入

函数被不同的执行流调用,有可能在第一次调用还没返回时就再次进入该函数,这称为重入。重入调用函数不会对预先设计好的代码执行逻辑产生影响的称为“可重入函数”。有可能因为重入而造成错乱,像这样的函数称为“不可重入函数”,

不可重入函数的特征:
①调用了malloc或free,因为malloc也是用全局链表来管理堆的。
②调用了标准I/O库函数。标准I/O库的很多实现都以不可重入的方式使用全局数据结构。
③修改了全局变量,因为全局变量在函数调用之间可能被修改,从而导致函数的行为不可预测。

  1. 执行流切换

执行流切换时,操作系统会保存当前任务的上下文信息,包括程序计数器、寄存器值、栈指针等。这些上下文信息被保存在任务的控制块中。 当调度器切换到另一个任务时,它会从该任务的控制块中恢复之前保存的上下文信息,使得该任务可以从上次中断的地方继续执行。

  1. 原子性

原子性指的是不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成,代码的原子性则指的是一行代码要么被执行完要么没开始执行。实际上如果不采取额外的措施,进程或线程切换无法保证代码的原子性的。因为一行代码往往有多条汇编代码组成,汇编代码的执行是原子的,C语言代码不是原子的。例如:
C代码 i++ 对应三条汇编指令:

load:将共享变量ticket从内存加载到寄存器中
update: 更新寄存器里面的值,执行-1操作
store:将新值,从寄存器写回共享变量ticket的内存地址

执行流在执行完load后可能被切换.I++语句没有被完全执行(故i++ 语句不是原子的),如果这个时候又有执行流对全局变量 i 进行操作,就可能会产生预期之外的结果。

  1. 临界资源

多线程执行流共享的资源(如全局变量)就叫做临界资源,每个线程内部,访问临界资源的代码,就叫做临界区。

  1. 互斥概念

根据前面对原子性,可重入概念的介绍,可以知道重入访问临界资源会产生错误,但多线程又有访问临界资源的需求,故有了互斥的概念和实现需求。
互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用。如果多个线程同时要求执行临界区的代码,并且临界区没有线程在执行,那么只能允许一个线程进入该临界区。如果线程不在临界区中执行,那么该线程不能阻止其他线程进入临界区。

互斥实际使用

//1.初始化互斥量锁——静态分配
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 
//1.初始化互斥量——动态分配 
//mutex:要初始化的互斥量 
int pthread_mutex_init(pthread_mutex_t *restrict mutex, 
const pthread_mutexattr_t*restrict attr);
//2.加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
//3.解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
//4.销毁锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);

使用逻辑图:
在这里插入图片描述
例子:

#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex;

void* thread_func(void* arg) 
{
    pthread_mutex_lock(&mutex); // 加锁
    printf("Thread %ld is inside the critical section\n", (long)arg);
    pthread_mutex_unlock(&mutex); // 解锁
    return NULL;
}

int main()
{
    pthread_t thread1, thread2;

    pthread_mutex_init(&mutex, NULL); // 初始化锁

    pthread_create(&thread1, NULL, thread_func, (void*)1);
    pthread_create(&thread2, NULL, thread_func, (void*)2);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    pthread_mutex_destroy(&mutex); // 销毁锁

    return 0;
}

注意:
①使用PTHREAD_ MUTEX_ INITIALIZER初始化的互斥量不需要销毁
②不要销毁一个已经加锁的互斥量,已经销毁的互斥量,要确保后面不会有线程再尝试加锁。
③互斥量处于未锁状态,该函数会将互斥量锁定,同时返回成功。如果互斥量处于锁住状态,那么pthread_ lock调用会陷入阻塞(执行流被挂起),等待互斥量解锁。(线程对互斥量(锁)的争取是原子的,即只有抢到互斥量和没抢到两种状态,同一个互斥量同一时间最多只能被一个线程锁定)。

互斥锁的原理

在这里插入图片描述
注意:
上下文 CPU寄存器 内存 是三个不同的存储空间 。
①先看lock伪代码部分,认识到lock函数本身是分多步完成的
②再看红字部分的问题
③按照数字序号,理解互斥锁的是如何实现的

死锁问题说明

死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。为了避免死锁问题,编写代码时需要保证代码逻辑①加锁顺序一致②避免锁未释放③资源一次性分配。

死锁的产生图解:
在这里插入图片描述

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

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

相关文章

MyBatis标签及其应用示例

MyBatis标签及其应用示例 1. select 1.1 标签属性 id唯一的标识符parameterType传给此语句的参数的全路径名或别名如&#xff1a;com.xxx.xxx.demo.entity.User或userresultType语句返回值类型或别名。如果是集合List&#xff0c;此处填写集合的泛型T&#xff0c;而不是集合…

人机交互中信息数量与质量

在人机交互中&#xff0c;信息的数量和质量都是非常重要的因素。 信息的数量指的是交互过程中传递的信息的多少。信息的数量直接影响到交互的效率和效果&#xff0c;如果交互中传递的信息量太少&#xff0c;可能导致交互过程中的信息不足&#xff0c;用户无法得到想要的结果或者…

js实时监听input输入框值的变化

实习日记之通过调用common chemistry的api接口实现输入keyword查找cas号和mw。做了一个简单的html网页&#xff0c;用到了ajax技术。比较简单&#xff0c;适合刚入门的宝学习参考。代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head>&l…

面试算法78:合并排序链表

题目 输入k个排序的链表&#xff0c;请将它们合并成一个排序的链表。 分析&#xff1a;利用最小堆选取值最小的节点 用k个指针分别指向这k个链表的头节点&#xff0c;每次从这k个节点中选取值最小的节点。然后将指向值最小的节点的指针向后移动一步&#xff0c;再比较k个指…

cleanmymac这个软件怎么样?值不值得下载

cleanmymac是我必装的mac端清理软件&#xff0c;界面简洁好看&#xff0c;完美适配mac系统&#xff0c;文件清理的速度、精度都比较优秀&#xff0c;还是比较不错的呢。cleanmymac作为一款第三方清洁应用程序&#xff0c;具有专业完整的清理功能&#xff0c;包括释放内存、一键…

Halcon阈值处理的几种分割方法threshold/auto_threshold/binary_threshold/dyn_threshold

Halcon阈值处理的几种分割方法 文章目录 Halcon阈值处理的几种分割方法1. 全局阈值2. 基于直方图的自动阈值分割方法3. 自动全局阈值分割方法4. 局部阈值分割方法5. var_threshold算子6 . char_threshold 算子7. dual_threshold算子 在场景中选择物体或特征是图像测量或识别的重…

FairyGUI-Cocos Creator官方Demo源码解读

博主在学习Cocos Creator的时候&#xff0c;发现了一款免费的UI编辑器FairyGUI。这款编辑器的能力十分强大&#xff0c;但是网上的学习资源比较少&#xff0c;坑比较多&#xff0c;主要学习方式就是阅读官方文档和练习官方Demo。这里博主进行官方Demo的解读。 从gitee上克隆项目…

《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(15)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识&#xff08;14&#xff09; 1.3 PCI总线的存储器读写总线事务 1.3.4 PCI读写主存储器 前文已提到&#xff0c;由于本节内容较长&#xff0c;因此将后一部分内容放在本文中。 为…

基于Python、Keras和OpenCV的实时人脸活体检测

你在互联网上找到的大多数人脸识别算法和研究论文都遭受照片攻击。这些方法在检测和识别来自网络摄像头的图像、视频和视频流中的人脸方面非常有效。然而&#xff0c;他们无法区分现实生活中的面孔和照片上的面孔。这种无法识别人脸的现象是由于这些算法在二维帧上工作。 现在…

【JS笔记】JavaScript语法 《基础+重点》 知识内容,快速上手(二)

数组 什么是数组&#xff1f; 字面理解就是 数字的组合 其实不太准确&#xff0c;准确的来说数组是一个 数据的集合 也就是我们把一些数据放在一个盒子里面&#xff0c;按照顺序排好 [1, 2, 3, hello, true, false]这个东西就是一个数组&#xff0c;存储着一些数据的集合 …

深度学习框架Keras与Pytorch对比

对于许多科学家、工程师和开发人员来说&#xff0c;TensorFlow是他们的第一个深度学习框架。TensorFlow 1.0于2017年2月发布&#xff0c;可以说&#xff0c;它对用户不太友好。 在过去的几年里&#xff0c;两个主要的深度学习库Keras和Pytorch获得了大量关注&#xff0c;主要是…

【Java EE初阶五】wait及notify关键字

1. wait和notify的概念 所谓的wait和notify其实就是等待、通知机制&#xff1b;该机制的作用域join类似&#xff1b;由于多个线程之间是随机调度的&#xff0c;引入wait和notify就是为了能够从应用层面上&#xff0c;干预到多个不同线程代码的执行顺序&#xff0c;此处的干预&a…

C# WPF上位机开发(Web API联调)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 很多时候&#xff0c;客户需要开发的不仅仅是一个上位机系统&#xff0c;它还有其他很多配套的系统或设备&#xff0c;比如物流小车、立库、数字孪…

web前端开发html/css求职简介/个人简介小白网页设计

效果图展示&#xff1a; html界面展示&#xff1a; html/css代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.…

Java IDEA JUnit 单元测试

JUnit是一个开源的 Java 单元测试框架&#xff0c;它使得组织和运行测试代码变得非常简单&#xff0c;利用JUnit可以轻松地编写和执行单元测试&#xff0c;并且可以清楚地看到哪些测试成功&#xff0c;哪些失败 JUnit 还提供了生成测试报告的功能&#xff0c;报告不仅包含测试…

VSCode + vite + vue3断点调试配置

没想到这个配置我搞了一上午&#xff0c;网上很多的配置方案都没有效果。总算搞定了&#xff0c;特此记录一下。 首先需要在.vscode文件夹下面创建launch.json配置文件。然后输入如下配置&#xff1a; {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。//…

Java Swing GUI实现ATM机(涉及网络编程聊天功能)

一、序言 1.首先这是本人大二时期的编程&#xff0c;涉及到网络编程的聊天功能&#xff0c;大佬勿喷。 二、且看展示图片 1.首先启动服务端&#xff08;启动Fuwuduan代码&#xff09;&#xff0c;也就是客服聊天窗口 提供给用户申请银行卡号&#xff0c;客服界面如下&#x…

复试 || 就业day01(2023.12.29)项目一

文章目录 前言正规方程二元一次示例正规方程 : w ( X T X ) − 1 X T y w (X^TX)^{-1}X^Ty w(XTX)−1XTy三元一次方程示例八元一次方程示例sklearn带截距的线性方程总结 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;…

unity exe程序置顶和全屏

1.置顶和无边框 设置显示位置和范围 using System; using System.Runtime.InteropServices; using UnityEngine; public class WindowMod : MonoBehaviour {public enum appStyle{FullScreen,WindowedFullScreen,Windowed,WindowedWithoutBorder}public enum zDepth{Normal…

手写Spring与基本原理--简易版

文章目录 手写Spring与基本原理解析简介写一个简单的Bean加载容器定义一个抽象所有类的BeanDefinition定义一个工厂存储所有的类测试 实现Bean的注册定义和获取基于Cglib实现含构造函数的类实例化策略Bean对象注入属性和依赖Bean的功能Spring.xml解析和注册Bean对象实现应用上下…