Linux——什么是互斥与互斥锁

article/2025/9/17 16:52:35

目录

一.前提:临界区 & 临界资源

二.什么是互斥

(一).互斥概念

(二).为什么需要互斥

三.互斥锁介绍

(一).互斥锁的概念

(二).互斥锁的使用

①系统API接口

②C++库

(三).互斥锁的底层原理

①加锁

②解锁


一.前提:临界区 & 临界资源

编写多线程程序时,多个线程可能需要执行同一个函数。如果该函数中有变量为这些线程共享,且可以改变,这样的变量可以称为临界资源

相对应的改变这些资源的代码就叫做临界区

示例如下代码:

int i = 0;//变量i为这些线程共享,即临界资源
void* func(void* arg){...//临界区起点i = 3;//临界区终点...
}int main(){pthread_t tid[2];pthread_create(&tid[0], nullptr, func, nullptr);pthread_create(&tid[1], nullptr, func, nullptr);pthread_join(tid[0], nullptr);pthread_join(tid[1], nullptr);return 0;
}

二.什么是互斥

(一).互斥概念

所谓互斥,其实就是在某一时刻只能有一个线程访问临界区,且完整的使用临界资源没有其他线程打扰,即原子性

简单来说就是当前线程使用完临界资源后其他线程才能来使用。

(二).为什么需要互斥

如果多个线程同时访问临界资源,那么可能造成很严重的后果。

举个例子:
如下代码:

std::cout >> i >> std::endl;
i--;

假设此时i == 1,当有多个线程同时执行时,可能会发生意向不到的情况。 

进行i--操作时,CPU其实分为三个步骤:

 当线程A执行i--时,如果在②步骤执行完毕后被操作系统突然切换为线程B,那么i值不会写回内存,而是作为上下文数据被该线程携带:

当线程B执行i--时,①步骤从内存中读取的是1之后②③步骤正常执行完毕,写回内存中,此时内存i值为0: 

如果此时再将线程A切回,那么会直接执行③步骤,也就是说会将内存值写为0,而这就与程序不符了。

明明是被两个线程执行过,i应该是-1,而结果却是0!

因此,当多线程使用临界区时,要确保只能有一个线程访问该临界资源,且必须是原子性的使用资源。

换一种说法就是,如果没有互斥保护,那么多线程访问临界资源就是并发执行;当有互斥保护时,多线程问临界资源就是串行执行

三.互斥锁介绍

(一).互斥锁的概念

互斥锁通俗来讲就是用来完成互斥行为的对象,锁住的范围一般就是临界区。

需要互斥操作的多线程共享一个互斥锁,当一个线程获得互斥锁后,其他线程会阻塞等待,直到当前线程归还互斥锁后,其他线程争抢互斥锁,谁获得了谁能进入临界区执行代码。

(二).互斥锁的使用

①系统API接口

头文件<pthread.h>

定义

pthread_mutex_t mtx;

初始化(两种方式):

pthread_mutex_init(&mtx, nullptr);//方式一
pthread_mutex_t mtx = PTHREAD_MUTEX_INITALIZER;//方式二

 加锁与解锁

lock与trylock的区别是,当多线程同时争抢互斥锁时,lock会让未抢到的线程阻塞等待,trylock不会阻塞等待

pthread_mutex_lock(&mtx);
...//临界区
pthread_mutex_unlock(&mtx);

 销毁

pthread_mutex_destroy(&mtx);

②C++库

头文件<mutex>

定义互斥锁对象

std::mutex mtx;

加锁与解锁

mtx.lock();//方式一,阻塞等待
mtx.try_lock();//方式二,非阻塞等待
...//临界区
mtx.unlock();

(三).互斥锁的底层原理

 底层汇编:

①加锁

1.

这一步是将0值写入al寄存器中。

图示:

2.

将al寄存器值与mutex值(即互斥量)交换,无锁时mutex值是1。

图示:

3.

如果al值大于0,即该线程获得锁,那么返回。如果没有获取锁,线程会阻塞,阻塞结束后跳转重新执行加锁过程。

图示:

对于线程B而言,当被调用后使用CPU时,此时mutex中值为0,al先被赋值为0,与mutex交换后值依旧为0,因此,当执行第三步时,会判断为else的情况,即阻塞等待。当线程A执行完毕解锁后,再经过goto语句,重新执行加锁过程。

总之,所谓加锁,其实就是所有线程抢占一个互斥量(1),抢到的给al寄存器,加锁成功;没抢到的,al寄存器值为0,阻塞等待。

②解锁

相对于加锁,解锁很简单,就是当线程执行完临界区后,将mutex中的值置为1即可。

这样,当其他线程抢锁时,mutex值为1,总会有一个线程加锁成功。

图示如下:


如有错误,敬请斧正 


http://chatgpt.dhexx.cn/article/iALDTl0P.shtml

相关文章

线程的互斥与同步

线程的互斥与同步 线程的互斥简单的抢票程序互斥量初始化互斥量销毁互斥量互斥量加锁和解锁 互斥量实现原理 可重入VS线程安全概念常见的线程不安全的情况常见的线程安全的情况常见不可重入的情况常见可重入的情况可重入与线程安全联系可重入与线程安全区别 死锁死锁四个必要条…

FreeRTOS个人笔记-互斥量

根据个人的学习方向&#xff0c;学习FreeRTOS。由于野火小哥把FreeRTOS讲得比较含蓄&#xff0c;打算在本专栏尽量细化一点。作为个人笔记&#xff0c;仅供参考或查阅。 配套资料&#xff1a;FreeRTOS内核实现与应用开发实战指南、野火FreeRTOS配套视频源码、b站野火FreeRTOS视…

C++ 互斥锁原理以及实际使用介绍

兄弟姐妹们&#xff0c;我又回来了&#xff0c;今天带来实际开发中都需要使用的互斥锁的内容&#xff0c;主要聊一聊如何使用互斥锁以及都有哪几种方式实现互斥锁。实现互斥&#xff0c;可以有以下几种方式&#xff1a;互斥量&#xff08;Mutex&#xff09;、递归互斥量&#x…

MySQL mutex互斥锁

在事务机制中&#xff0c;锁机制是为了保证高并发&#xff0c;数据一致性的重要实现方式。MySQL除了Innodb引擎层面的行锁&#xff0c;还有latch锁。latch锁的作用资源协调处理。包含表句柄&#xff0c;线程&#xff0c;cpu线程&#xff0c;内存池等。其保证非常短时间内快速处…

uCOSii中的互斥信号量

uCOSii中的互斥信号量 一、互斥型信号量项管理 (MUTUAL EXCLUSION SEMAPHORE MANAGEMENT) OSMutexAccept() 无条件等待地获取互斥型信号量 OSMutexCreate() 建立并初始化一个互斥型信号量 OSMutexDel() 删除互斥型信号量 OSMutexPend() 等待一个互斥型信号量 OSMutexPost…

互斥信号量

目录 1、Creat 2、Delete 3、Wait 4、Post 5、Statu 互斥信号量 在介绍二进制信号量时&#xff0c;曾讨论到如果二进制信号量创建时设置参数 bInitValue 为TRUE&#xff0c;则可以用于互斥访问共享资源。实际上&#xff0c;SylixOS 的二进制信号量实现的互斥性是将一个变量…

UCOS-III 互斥量

互斥量 一、互斥量基本概念二、互斥量优先级继承机制三、互斥量应用场景四、互斥量运作机制五、互斥量创建流程1、定义互斥量2、创建互斥量 六、互斥量接口函数1、创建互斥量函数OSMutexCreate()2、删除互斥量函数 OSMutexDel()3、获取互斥量函数 OSMutexPend()4、释放互斥量函…

互斥量知识

文章目录 互斥量1、基本概念2、互斥量的优先级继承机制3、互斥量应用场景4、互斥量运行机制5、互斥量控制块6、互斥量函数接口&#xff08;1&#xff09;互斥量创建函数 xSemaphoreCreateMutex()&#xff08;2&#xff09;递归互斥量创建函数 xSemaphoreCreateRecursiveMutex()…

同步和互斥

同步和互斥 竞争与协作 在单核 CPU 系统里&#xff0c;为了实现多个程序同时运行的假象&#xff0c;操作系统通常以时间片调度的方式&#xff0c;让每个进程执行每次执行一个时间片&#xff0c;时间片用完了&#xff0c;就切换下一个进程运行&#xff0c;由于这个时间片的时间很…

多线程的同步与互斥(互斥锁、条件变量、读写锁、自旋锁、信号量)

文章目录 一、同步与互斥的概念二、互斥锁&#xff08;同步&#xff09;三、条件变量&#xff08;同步&#xff09;1、线程的条件变量实例12、线程的条件变量实例23、虚假唤醒(spurious wakeup) 四、读写锁&#xff08;同步&#xff09;五、自旋锁&#xff08;同步&#xff09;…

同步和互斥区别

互斥的概念 由于多线程执行操作共享变量的这段代码可能会导致竞争状态&#xff0c;因此我们将此段代码称为临界区&#xff08;critical section&#xff09;&#xff0c;它是访问共享资源的代码片段&#xff0c;一定不能给多线程同时执行。 我们希望这段代码是互斥&#xff0…

操作系统——互斥的定义及实现

一、进程互斥的定义 所谓进程互斥,指的是对某个系统资源,一个进程正在使用它,另外一个想用它的进程就必须等待,而不能同时使用 。进程互斥是多道程序系统中进程间存在的一种源于资源共享的制约关系,也称间接制约关系,主要是由被共享资源的使用性质所决定的。 二、互斥…

Fisher判别分析详解

Fisher判别分析 将高维度空间的样本投影到低维空间上&#xff0c;使得投影后的样本数据在新的子空间上有最小的类内距离以及最大的类间距离&#xff0c;使得在该子空间上有最佳的可分离性 可以看出右侧投影后具有更好的可分离性。 Fisher判别分析和PCA差别 刚学完感觉两个很…

基于spss的多元统计分析 之 聚类分析+判别分析(2/8)

实验目的&#xff1a; 1&#xff0e;掌握聚类分析及判别分析的基本原理&#xff1b; 2&#xff0e;熟悉掌握SPSS软件进行聚类分析及判别分析的基本操作&#xff1b; 3&#xff0e;利用实验指导的实例数据&#xff0c;上机熟悉聚类分析及判别分析方法。 实验前预习&#xff1a;…

机器学习——线性判别分析

目录 线性判别分析 LDA的降维过程 案例&#xff1a;鸢尾花(Iris) 代码演示 数据集 局部线性嵌入 线性判别分析 线性判别分析&#xff08;LDA&#xff09;是一种有监督的线性降维算法。与PCA不同&#xff0c;LDA是为了使降维后的数据点尽可能地容易被区分。 线性判别分析…

MATLAB判别分析例题,判别分析的matlab实现案例.doc

判别分析的matlab实现案例.doc 读取EXAMP10_01XLS中数据&#xff0c;进行距离判别读取数据读取文件EXAMP10_01XLS的第1个工作表中C2F51范围的数据&#xff0c;即全部样本数据&#xff0c;包括未判企业SAMPLEXLSREAD EXAMP10_01XLS , , C2F51 读取文件EXAMP10_01XLS的第1个工作…

SAS数据分析之判别分析

判别分析与聚类分析有非常类似的特性&#xff0c;因此&#xff0c;在多数数据分析的教材中&#xff0c;这两章是一前一后出现的&#xff0c;简而言之&#xff0c;聚类分析&#xff0c;其实是判别分析的基础&#xff0c;即在聚类分析的基础上&#xff0c;总结出各类的权值&#…

线性判别分析

线性判别分析&#xff08;LDA&#xff09;是一种经典的线性学习方法。其思想是&#xff1a;给定训练样例集&#xff0c;设法将样例投影到一条直线上&#xff0c;使得同类样例的投影点尽可能接近、异类样例的投影点尽可能远离。如图所示的二分类示意图&#xff1a; 损失函数的…

sas判别分析

#判别分析两大类&#xff1a;Fisher&Bayes #neighbbor&#xff1a;马氏距离和欧氏距离&#xff1b; #典型判别分析&#xff0c;联系典型相关分析#组变量相关&#xff0c;最后得到的每组内变量的线性组合作为典型变量 #协方差矩阵&#xff0c;举个栗子,设一组特征x(a1,a…

【数模】判别分析

文章目录 判别分析简介SPSS操作步骤输出结果分析 判别分析简介 判别分析又称“分辨法”&#xff0c;是在分类确定的条件下&#xff0c;根据某一研究对象的各种特征值判别其类型归属问题的一种多变量统计分析方法。 其基本原理是按照一定的判别准则&#xff0c;建立一个或多个判…