Linux网络编程【死锁】

举报
xcc-2022 发表于 2022/10/24 21:00:54 2022/10/24
【摘要】 3.9 死锁(DeadLock)1)什么是死锁死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的==一种阻塞的现象==,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。2)死锁引起的原因竞争不可抢占资源引起死锁也就是我们说的第一种情况,而这都在等待对方占有的不可抢占的资源。竞争可消耗资源引起死锁有...

3.9 死锁(DeadLock)

image-20220927113635278

1)什么是死锁

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的==一种阻塞的现象==,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

2)死锁引起的原因

竞争不可抢占资源引起死锁

也就是我们说的第一种情况,而这都在等待对方占有的不可抢占的资源。

竞争可消耗资源引起死锁

有p1,p2,p3三个进程,p1向p2发送消息并接受p3发送的消息,p2向p3发送消息并接受p1的消息,p3向p1发送消息并接受p2的消息,如果设置是先接到消息后发送消息,则所有的消息都不能发送,这就造成死锁。

进程推进顺序不当引起死锁

有进程p1,p2,都需要资源A,B,本来可以p1运行A --> p1运行B --> p2运行A --> p2运行B,但是顺序换了,p1运行A时p2运行B,容易发生第一种死锁。互相抢占资源。

3)死锁的必要条件

互斥条件

某资源只能被一个进程使用,其他进程请求该资源时,只能等待,直到资源使用完毕后释放资源。

请求和保持条件

程序已经保持了至少一个资源,但是又提出了新要求,而这个资源被其他进程占用,自己占用资源却保持不放。

不可抢占条件

进程已获得的资源没有使用完,不能被抢占。

循环等待条件

必然存在一个循环链。

4)处理死锁的思路

预防死锁

破坏死锁的四个必要条件中的一个或多个来预防死锁。

避免死锁

和预防死锁的区别就是,在资源动态分配过程中,用某种方式防止系统进入不安全的状态。

检测死锁

运行时出现死锁,能及时发现死锁,把程序解脱出来

解除死锁

发生死锁后,解脱进程,通常撤销进程,回收资源,再分配给正处于阻塞状态的进程。

5)预防死锁的方法

*破坏请求和保持条件*

协议1:

所有进程开始前,必须一次性地申请所需的所有资源,这样运行期间就不会再提出资源要求,破坏了请求条件,即使有一种资源不能满足需求,也不会给它分配正在空闲的资源,这样它就没有资源,就破坏了保持条件,从而预防死锁的发生。

协议2:

允许一个进程只获得初期的资源就开始运行,然后再把运行完的资源释放出来。然后再请求新的资源。

*破坏不可抢占条件*

当一个已经保持了某种不可抢占资源的进程,提出新资源请求不能被满足时,它必须释放已经保持的所有资源,以后需要时再重新申请。

*破坏循环等待条件*

对系统中的所有资源类型进行线性排序,然后规定每个进程必须按序列号递增的顺序请求资源。假如进程请求到了一些序列号较高的资源,然后有请求一个序列较低的资源时,必须先释放相同和更高序号的资源后才能申请低序号的资源。多个同类资源必须一起请求。

代码:

pthread_mutex_t  mutex1;
pthread_mutex_t  mutex2;
//线程1处理函数
void* fun1(void *arg)
{
    //先申请资源1,再申请资源2
    pthread_mutex_lock(&mutex1);
    printf("线程1加锁资源1成功...\n");
    pthread_mutex_lock(&mutex2);
    printf("线程1加锁资源2成功...\n");
    
   printf("线程1执行临界区代码...\n"); 

    //解锁
    pthread_mutex_unlock(&mutex1);
    pthread_mutex_unlock(&mutex2);
    return NULL;
}
//线程2处理函数
void* fun2(void *arg)
{
    //先申请资源2,再申请资源1
    pthread_mutex_lock(&mutex2);
    printf("线程2加锁资源2成功...\n");
    pthread_mutex_lock(&mutex1);
    printf("线程2加锁资源1成功...\n");

   printf("线程2执行临界区代码...\n"); 

    //解锁
    pthread_mutex_unlock(&mutex2);
    pthread_mutex_unlock(&mutex1);
    return NULL;
}
int main()
{

    int ret = -1;
    pthread_t tid1, tid2;

    //初始化互斥量,互斥锁
    pthread_mutex_init(&mutex1,NULL);
    pthread_mutex_init(&mutex2,NULL);
    //创建两个线程
    pthread_create(&tid1,NULL,fun1,NULL);
    pthread_create(&tid2,NULL,fun2,NULL);

    //等待两个线程结束
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    //销毁互斥锁
    pthread_mutex_destroy(&mutex1);
    pthread_mutex_destroy(&mutex2);

    return 0;
}

image-20220927123128736

运行结果:

image-20220927122426442

解决这个死锁问题可以同时申请资源1;

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。