Linux系统编程(18)——互斥-互斥锁、死锁

博客介绍了互斥机制,因线程抢占式执行引发线程安全问题,可在临界区使用互斥锁解决。阐述了互斥锁相关函数及使用方法,通过代码实例说明其能保证线程安全但影响效率。还指出互斥锁会引发死锁,介绍常见场景并提及有简单粗暴的解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

互斥机制的原因:

线程的抢占式执行,引起线程安全问题(多线程环境下程序的执行结果出现预期结果之外的值
)。主要在公共资源的使用上才会显示最大问题。


多个线程访问的那个公共资源叫做——临界资源

访问临界资源的代码叫做——临界区


在临界区使用 互斥机制 就能解决线程不安全问题

互斥机制的使用:使用互斥锁互斥锁就像ATM取钱

  1. 先加锁
  2. 执行临界区代码
  3. 释放锁

同一时刻只有一个线程才能执行临界区代码其他线程只能等待锁的释放


 互斥锁相关函数:

位置在主函数中:

pthread_mutex_init(&mutex,NULL):初始化锁,一定要初始化

pthread_mutex_destory(&mutex):释放锁

定义全局函数位置定义:

pthread_mutex_t mutex:定义一个互斥锁

需要互斥锁就加在需要函数的位置中:

pthread_mutex_lock(&mutex):上锁

pthread_mutex_unlock(&mutex):开锁


互斥锁也叫挂起等待锁,一旦线程获取锁失败就会挂起进入操作系统的等待队列中)这个线程什么时候才能恢复执行,也不是其他线程释放锁立即就能恢复执行而是其他线程释放锁,当前线程还要看操作系统的心情来决定啥时候恢复执行

代码实例: 

//多线程求g_count 的值

#include <stdio.h>
#include<pthread.h> //头文件

#define THERAD_NUM 2

//定义一个互斥锁
pthread_mutex_t mutex;

int g_count = 0;
void* ThreadEntry(void* arg) {  //新线程入口,参数
	(void)arg;
	for (int i = 0; i < 50000;++i)
	{
		//如果锁已经被其他线程获取到了,当线程在想获取,就会在lock 函数阻塞
		pthread_mutex_lock(&mutex);//上锁
		++g_count;
		pthread_mutex_unlock(&mutex); //开锁
	}
	return NULL;
}

int main() {
	//主线程

	pthread_t tid[THERAD_NUM];
	pthread_mutex_init(&mutex, NULL);//互斥锁初始化函数

	for (int i = 0; i < THERAD_NUM; ++i) {
		pthread_create(&tid[i], NULL, ThreadEntry, &args[i]);
	}
	for (int i = 0; i < 50000; ++i)
	{
		++g_count;
	}
	for (int i = 0; i < THERAD_NUM; ++i) {  //释放新线程
		pthread_join(tid[i], NULL);
	}
	printf("%d", g_count);

	pthread_mutex_destory(&mutex);//互斥锁释放函数

	return 0;
}

结果就是:1000000;如果不加互斥锁结果就是未知,随意的,偶尔得到100000.


互斥锁能够保证线程的安全,最终的程序效率会有影响,但是会引发新的问题更严重的问题——死锁 !!!

死锁

死锁的常见的场景:

  1. 一个线程连续两次的加锁(加了一次锁,再次尝试加锁)
  2. 两个线程1、2;两把锁A、B;线程1 先获取锁A,在获取锁B;线程2 先获取锁B,再获取锁B;就会引起死锁

(第二个就是:拿着筷子你朋友拿着勺子,但是你要勺子,朋友要筷子。这时候,你说:你先把勺子给我我在给你筷子。你朋友说:你先把筷子给我我在给你勺子。两个人互不相让,这时候就陷入死锁了。——类似哲学家吃饭问题,经典的死锁场景


如何解决死锁问题?

实用操作时一个简单粗暴的方法,但是很有效

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值