linux 线程 死锁

死锁:🔴⚫🟤🟣🔵🟢🟡🟠

  有时,一个线程需要同时访问两个或更多不同的共享资源,而每个资源又都由不同的互斥量管理。当超过一个线程加锁同一组互斥量时,就有可能发生死锁。

  两个或两个以上的进程在执行过程中,因争夺共享资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。

  死锁的几种场景:

    🔴 忘记释放锁

    🔴 重复加锁

    🔴 多线程多锁,抢占锁资源(互相等待  A持有资源1 等待资源2  B持有资源2 等待资源1)

主代码:

复制代码
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <unistd.h>
 4 int tickets = 500;
 5 //创建一个互斥量
 6 pthread_mutex_t mutex;//全局变量
 7 void * sellticket(void * arg)
 8 {
 9     //A B C A先进 然后加锁 执行while 解锁 B C A都有机会执行代码区  有解锁后才可以进行执行 
10     //卖票
11     while(1)
12     { 
13         //加锁
14         pthread_mutex_lock(&mutex);
15         if(tickets > 0)
16         {
17             usleep(6000);
18             printf("%ld 正在卖第 %d 张门票\n",pthread_self(),tickets);
19             tickets--;
20         }
21         else 
22         {
23             // = 0 解锁
24             pthread_mutex_unlock(&mutex);
25             break;
26         }
27         //解锁  
28         pthread_mutex_unlock(&mutex);
29     } 
30     return NULL;
31 }
32 int main()
33 {
34     //初始化
35     pthread_mutex_init(&mutex, NULL);
36     //创建3个子线程
37     pthread_t tid1,tid2,tid3;
38     pthread_create(&tid1, NULL, sellticket, NULL);
39     pthread_create(&tid2, NULL, sellticket, NULL);
40     pthread_create(&tid3, NULL, sellticket, NULL);
41     //回收子线程的资源, 阻塞
42     pthread_join(tid1,NULL);
43     pthread_join(tid2,NULL);
44     pthread_join(tid3,NULL);
45     pthread_exit(NULL);//退出主线程
46     //释放互斥量资源
47     pthread_mutex_destroy(&mutex);
48     return 0;
49 }
复制代码

1.忘记释放锁:

复制代码
 1 void * sellticket(void * arg)
 2 {
 3     while(1)
 4     { 
 5         pthread_mutex_lock(&mutex);
 6         if(tickets > 0)
 7         {
 8             usleep(6000);
 9             printf("%ld 正在卖第 %d 张门票\n",pthread_self(),tickets);
10             tickets--;
11         }
12         else 
13         {
14             // = 0 解锁
15             pthread_mutex_unlock(&mutex);
16             break;
17         }
18         //解锁  
19         //pthread_mutex_unlock(&mutex);//忘记释放锁   会导致死锁,程序不正常执行
20     } 
21     return NULL;
22 }
复制代码

2.重复加锁

复制代码
void * sellticket(void * arg)
{
    while(1)
    { 
        pthread_mutex_lock(&mutex);//加锁
        pthread_mutex_lock(&mutex);//重复加锁
        if(tickets > 0)
        {
            usleep(6000);
            printf("%ld 正在卖第 %d 张门票\n",pthread_self(),tickets);
            tickets--;
        }
        else 
        {
            pthread_mutex_unlock(&mutex);// = 0 解锁
            break;
        }
        pthread_mutex_unlock(&mutex);//解锁
        pthread_mutex_unlock(&mutex);//重复解锁 但用不到  程序阻塞
    } 
    return NULL;
}
复制代码

3.多线程多锁:

复制代码
 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <pthread.h>
 4 #include <string.h> 
 5 //创建两个互斥量
 6 pthread_mutex_t mutex1,mutex2;
 7 void * workA(void * arg)//arg:argument 传参
 8 {
 9     pthread_mutex_lock(&mutex1);
10     sleep(1);
11     pthread_mutex_lock(&mutex2);
12     printf("workA...\n");
13     pthread_mutex_unlock(&mutex2);
14     pthread_mutex_unlock(&mutex1);
15     return NULL;
16 }
17 void * workB(void * arg)
18 {
19     pthread_mutex_lock(&mutex2);
20     sleep(1);
21     pthread_mutex_lock(&mutex1);
22     printf("workB...\n");
23     pthread_mutex_unlock(&mutex1);
24     pthread_mutex_unlock(&mutex2);
25     return NULL;
26 }
27 int main()
28 {
29     // 初始化两个互斥量
30     pthread_mutex_init(&mutex1,NULL);
31     pthread_mutex_init(&mutex2,NULL);
32     //创建2个子线程
33     pthread_t tid1,tid2;
34     pthread_create(&tid1,NULL,workA,NULL);
35     pthread_create(&tid2,NULL,workB,NULL);
36     //回收子线程资源
37      pthread_join(tid1,NULL);
38      pthread_join(tid2,NULL);
39     //释放互斥量资源
40     pthread_mutex_destroy(&mutex1);
41     pthread_mutex_destroy(&mutex2);
42     return 0;
43 }
复制代码

posted on   廿陆  阅读(27)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示