Linux系统编程—线程—什么情况造成死锁

Posted 是光哥呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux系统编程—线程—什么情况造成死锁相关的知识,希望对你有一定的参考价值。

死锁产生的原因
1、系统资源的竞争
通常系统中拥有的不可剥夺资源,其数量不足以满足多个线程运行的需要,使得线程在 运行过程中,会因争夺资源而陷入僵局,如磁带机、打印机等。只有对不可剥夺资源的竞争 才可能产生死锁,对可剥夺资源的竞争是不会引起死锁的。
2、线程推进顺序非法
线程在运行过程中,请求和释放资源的顺序不当,也同样会导致死锁。例如,并发线程 P1、P2分别保持了资源R1、R2,而线程P1申请资源R2,线程P2申请资源R1时,两者都 会因为所需资源被占用而阻塞。
3、信号量使用不当也会造成死锁。线程间彼此相互等待对方发来的消息,结果也会使得这 些线程间无法继续向前推进。例如,线程A等待线程B发的消息,线程B又在等待线程A 发的消息,可以看出线程A和B不是因为竞争同一资源,而是在等待对方的资源导致死锁。

死锁产生的必要条件
产生死锁必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生。

1、互斥条件:线程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某资源仅为一个线程所占有。此时若有其他线程请求该资源,则请求线程只能等待
2、不剥夺条件:线程所获得的资源在未使用完毕之前,不能被其他线程强行夺走,即只能 由获得该资源的线程自己来释放(只能是主动释放)
3、请求和保持条件:线程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他线程占有,此时请求线程被阻塞,但对自己已获得的资源保持不放
4、循环等待条件:存在一种线程资源的循环等待链,链中每一个线程已获得的资源同时被 链中下一个线程所请求。即存在一个处于等待状态的线程集合{Pl, P2, …, pn},其中Pi等 待的资源被P(i+1)占有(i=0, 1, …, n-1),Pn等待的资源被P0占有

解决死锁的方法:
目前有两种方法,一是不让死锁发生;二是可以允许死锁发生,发生后再加以解决。具体有以下4种方法:
1、预防死锁。通过设置某些严格限制破坏死锁产生的条件防止死锁发生,但该方法会导致系统资源利用率过低。
2、避免死锁。在资源动态分配过程中,采用某种方法防止系统进入不安全状态,避免发生死锁。该方法以较弱的限制条件为代价,可获得较高的资源利用。
3、检测死锁。允许系统运行过程中产生死锁,通过在系统中设置检测机构,及时检测出死锁是否真的发生,并能精确的确定与死锁有关的进程与资源,然后采取措施解除死锁。
4、解除死锁。这是与检测死锁相配套的措施,用于将进程从死锁状态下解脱出来。

====================================================
当线程a有一把锁想要获得另外一把锁,线程 b手里握着线程a想要获得的那把锁同时想要获得线程a的那把锁,这样线程a线程b都想要获得对方的那把锁,谁都不肯往下去解锁,导致线程死锁

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t m;
pthread_mutex_t m2;

void *func1(void *arg)
{
        int i;

        pthread_mutex_lock(&m);
        sleep(1);
        pthread_mutex_lock(&m2);
        for(i=0;i<5;i++){
                printf("t1:%ld thread is create\\n",(unsigned long)pthread_self());
                printf("t1:param is %d\\n",*((int *)arg));
                sleep(1);
        }
        pthread_mutex_unlock(&m);
}

void *func2(void *arg)
{
        pthread_mutex_lock(&m2);

        sleep(1);
        pthread_mutex_lock(&m);
        printf("t2:%ld thread is create\\n",(unsigned long)pthread_self());
        printf("t2:param is %d\\n",*((int *)arg));

        pthread_mutex_unlock(&m);
}
int main()
{
        int ret;
        int param=100;

        pthread_t t1;
        pthread_t t2;
        pthread_mutex_init(&m,NULL);
        pthread_mutex_init(&m2,NULL);

        ret=pthread_create(&t1,NULL,func1,(void *)&param);
        if(ret==0){
                printf("main create t1 success\\n" );
        }

        ret=pthread_create(&t2,NULL,func2,(void *)&param);
        if(ret==0){
                printf("main create t2 success\\n" );
        }

        printf("main:%ld\\n",(unsigned long)pthread_self());

        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_mutex_destroy(&m);
        pthread_mutex_destroy(&m2);

        return 0;
}

运行结果:main函数卡在这,t1、t2无法运行
在这里插入图片描述

以上是关于Linux系统编程—线程—什么情况造成死锁的主要内容,如果未能解决你的问题,请参考以下文章

死锁的理解

死锁的产生原因以及解决方案

多线程编程之线程死锁问题

python 并发编程 多线程 死锁现象与递归锁

Linux下面 多线程死锁问题的调试

8.Python网络编程_多线程死锁