Linux多线程10-死锁
有时,一个线程需要同时访问两个或更多不同的共享资源,而每个资源又都由不同的互斥量管理。当超过一个线程加锁同一组互斥量时,就有可能发生死锁。
两个或两个以上的进程在执行过程中,因争夺共享资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。
死锁的几种场景:
- 忘记释放锁
- 重复加锁
- 多线程多锁,抢占锁资源
代码示例:
-
重复加锁或忘记解锁的情况
#include <stdio.h> #include <pthread.h> #include <unistd.h> int tickets = 1000; //所有线程都共享这100张票 //创建一个互斥量 pthread_mutex_t mutex; void* sellticket(void* arg){ while(1){ //加锁 pthread_mutex_lock(&mutex); //重复加锁 //pthread_mutex_lock(&mutex); //程序卡住 无法执行 if(tickets > 0){ // 卖票 // 我们要求在A线程操作共享数据时, B,C线程不允许操作 usleep(6000); printf("%ld 正在卖第 %d 张门票\n", pthread_self(), tickets); tickets--; }else{ pthread_mutex_unlock(&mutex); break; } //解锁 pthread_mutex_unlock(&mutex); //忘记解锁会程序阻塞产生死锁 } return NULL; } int main(){ //初始化互斥量 pthread_mutex_init(&mutex, NULL); //创建3个子线程 pthread_t tid1, tid2, tid3; pthread_create(&tid1, NULL, sellticket, NULL); pthread_create(&tid2, NULL, sellticket, NULL); pthread_create(&tid3, NULL, sellticket, NULL); //回收子线程资源, 阻塞 pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_join(tid3, NULL); pthread_exit(NULL); //退出主线程 //释放互斥量资源 pthread_mutex_destroy(&mutex); return 0; }
-
多线程多锁, 抢占锁资源
#include <stdio.h> #include <pthread.h> #include <unistd.h> //创建两个互斥量 pthread_mutex_t mutex1, mutex2; void* workA(void* arg){ pthread_mutex_lock(&mutex1); sleep(1); pthread_mutex_lock(&mutex2); printf("workA...\n"); pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex1); return NULL; } void* workB(void* arg){ pthread_mutex_lock(&mutex2); sleep(1); pthread_mutex_lock(&mutex1); printf("workB...\n"); pthread_mutex_unlock(&mutex1); pthread_mutex_unlock(&mutex2); return NULL; } int main(){ //初始化互斥量 pthread_mutex_init(&mutex1, NULL); pthread_mutex_init(&mutex2, NULL); //创建2个子线程 pthread_t tid1, tid2; pthread_create(&tid1, NULL, workA, NULL); pthread_create(&tid2, NULL, workB, NULL); //回收子线程资源 pthread_join(tid1, NULL); pthread_join(tid2, NULL); //释放互斥量资源 pthread_mutex_destroy(&mutex1); pthread_mutex_destroy(&mutex2); return 0; }