互斥锁导致的死锁
operating systemwindowsmca更新于 2026/2/6 12:52:17
在使用互斥锁的多线程 Pthread 程序中,可能会发生死锁。让我们看看它是如何发生的。未锁定的互斥锁由 pthread_mutex_init() 函数初始化。
使用 pthread_mutex_lock() 和 pthread_mutex_unlock() 函数获取并释放互斥锁。如果一个线程尝试获取已锁定的互斥锁,则调用 pthread_mutex_lock() 会阻塞该线程,直到互斥锁的所有者调用 pthread_mutex_unlock()。
举个例子,以下代码创建了两个互斥锁 −
/* 创建并初始化互斥锁 */ pthread mutex t mutex1; pthread mutex t mutex2; pthread mutex init(&mutex1,NULL); pthread mutex init(&mutex2,NULL);
接下来,创建两个线程 - thread1 和 thread2,这两个线程都可以访问两个互斥锁。Thread1 和 thread2 分别在函数 dosomework_1 和 dosomework_2 中运行,如下所示 −
/* thread1 在此函数中运行 */
void *dosomework_1(void *param) {
pthread mutex lock(&mutex1);
pthread mutex lock(&mutex2);
/**
* 执行一些工作 */
pthread mutex unlock(& mutex2);
pthread mutex unlock(& mutex2);
pthread exit(0); } /*
thread2 在此函数中运行
*/ void *dosomework_2(void *param) {
pthread mutex lock(&mutex2);
pthread mutex lock(&mutex1);
/**
* 执行一些工作 */
pthread mutex unlock(&mutex1);
pthread mutex unlock(&mutex2);
pthread exit(0);
}
在此示例中,线程 1 尝试按以下顺序获取互斥锁
- 互斥锁 1,
- 互斥锁 2,
而线程 2 尝试按以下顺序获取互斥锁
- 互斥锁 2,
- 互斥锁 1,
如果线程 1 获取了互斥锁 1,而线程 2 获取了互斥锁 2,则可能发生死锁。即使可能发生死锁,如果线程 1 能够在线程 2 尝试获取互斥锁之前获取并释放互斥锁 1 和互斥锁 2,则不会发生死锁。当然,CPU 调度程序会调度线程的运行顺序。上述示例说明了处理死锁的一个问题:很难识别和测试仅在特定调度情况下才会发生的死锁。