0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

两个线程和互斥锁如何形成死循环?

璟琰乀 来源:一口Linux 作者:一口Linux 2021-01-02 16:47 次阅读

两个线程,两个互斥锁如何形成死锁?程序流程图如下:

UF7nYf.png

程序流程图

如上图所示:

t0时刻,主线程创建子线程,并初始化互斥锁mutex1、mutex2;

t1时刻,主线程申请到了mutex1、子线程申请到了mutex2;

t2时刻,主线程和子线程都sleep 1秒钟,防止优先获得时间片的线程直接申请到了另外1个互斥锁,导致程序直接退出;

t3时刻,主线程和子线程都想获得对方手里的互斥锁,但是对方都来不及释放自己手里的锁;

t4时刻,主线程和子线双双进入休眠。

【注意】为了保证主线程和子线程都能够分别获得锁mutex1、mutex2,各自获得锁后一定要先sleep 1秒钟,否则创建完子线程后,主线程还有一定的时间片,主线程会申请到锁mutex2,无法形成死锁。

死锁

源码如下#include 《stdio.h》#include 《stdlib.h》#include 《string.h》#include 《pthread.h》 unsigned int value1, value2, count;pthread_mutex_t mutex1,mutex2;void *function(void *arg);void *function(void *arg){ pthread_mutex_lock(&mutex2); printf(“new thread get mutex2 ”); sleep(1); pthread_mutex_lock(&mutex1); printf(“new thread get mutex1 ”); pthread_mutex_unlock(&mutex1); printf(“new thread release mutex1 ”); pthread_mutex_unlock(&mutex2); printf(“new thread release mutex2 ”); return NULL; } int main(int argc, char *argv[]){ pthread_t a_thread; if (pthread_mutex_init(&mutex1, NULL) 《 0) { perror(“fail to mutex_init”); exit(-1); } if (pthread_mutex_init(&mutex2, NULL) 《 0) { perror(“fail to mutex_init”); exit(-1); } if (pthread_create(&a_thread, NULL, function, NULL) 《 0) { perror(“fail to pthread_create”); exit(-1); } while ( 1 ) { pthread_mutex_lock(&mutex1); printf(“main thread get mutex1 ”); sleep(1); pthread_mutex_lock(&mutex2); printf(“main thread get mutex2 ”); pthread_mutex_unlock(&mutex2); printf(“main thread release mutex2 ”); pthread_mutex_unlock(&mutex1); printf(“main thread release mutex1 ”); } return 0; }

编译运行

Q7reqy.png

从执行结果可以判断,主线程和子线程分别获得了互斥锁mutex1、mutex2,sleep 1秒后,他们都想再分别申请mutex2、mutex1,而双方都不想释放自己手中的锁,锁已形成了死锁,程序就一直处于休眠状态。

查看下该进程的线程查看进程ID,为4204

qaYFb2.png

查看该进程创建的线程id:4204、4205。

MZJJb2.png

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    88

    文章

    3627

    浏览量

    93809
  • 线程
    +关注

    关注

    0

    文章

    505

    浏览量

    19705
收藏 人收藏

    评论

    相关推荐

    sr存器特性表q为什么有两个

    SR存器特性表中Q之所以有两个值,是因为这些值分别代表了存器在不同输入条件下的状态。具体来说,Q的两个值分别对应了存器的“当前状态”(
    的头像 发表于 08-28 09:28 793次阅读

    互斥和自旋的实现原理

    互斥和自旋是操作系统中常用的同步机制,用于控制对共享资源的访问,以避免多个线程或进程同时访问同一资源,从而引发数据不一致或竞争条件等问题。 互斥
    的头像 发表于 07-10 10:07 518次阅读

    自旋互斥的使用场景是什么

    自旋互斥种常见的同步机制,它们在多线程编程中被广泛使用。在本文中,我们将介绍自旋
    的头像 发表于 07-10 10:05 1044次阅读

    两个铜片可以形成原电池吗

    两个铜片本身不能形成原电池,因为原电池的工作原理依赖于两个不同电位的电极材料之间的氧化还原反应。
    的头像 发表于 05-21 16:23 1020次阅读

    STM32F3执行函数的时候进入HardFault_Handler死循环,怎么处理?

    + (uint32_t)(dataRx1 << 16)); return *Result; } 执行这个函数的时候进入HardFault_Handler死循环,求助怎么处理?函数功能是从某个芯片中读取两个字,网上都说是接收缓冲区小了,请问各位怎么处理啊?
    发表于 05-13 07:35

    创建了两个task如果一优先级高 一优先级低,高优先级的那个一直在做,什么时候会调度到低优先级的呢?

    创建了两个task如果一优先级高一优先级低, 我看到任务的函数都是用死循环做的,那个高优先级的那个一直在做,什么时候会调度到低优先级的呢?
    发表于 05-13 07:13

    STM32F107中断死循环的原因?

    STM32F107,中断死循环
    发表于 05-11 06:31

    在freertos中,每个任务都是一死循环,那么还需要使用看门狗吗?

    在freertos中,每个任务都是一死循环,那么还需要使用看门狗吗?该怎么使用?
    发表于 05-07 06:55

    聊聊MCU死循环,用for(;;)还是while(1)?

    首先,问大家一问题:你们写单片机程序【死循环】时,喜欢用for(;;)还是while(1)?快来为你喜欢用的【死循环】打call,评论区等你哦~一位工程师发现,国外工程师在给demo在做死循
    的头像 发表于 04-29 08:10 1397次阅读
    聊聊MCU<b class='flag-5'>死循环</b>,用for(;;)还是while(1)?

    关于FreeRTOS互斥量的用法求解

    会引起死,比如当同一任务多次抢占时, 最后还是得换到互斥量, 基于串口中断发送模式, 希望使用互斥量来访问串口的话 , 该如何释放发送完成信号呢? 在中断函数中释放
    发表于 04-24 08:03

    如何让同一条件结构里的两个循环同时独立运行

    由于两个循环里都用了定时功能,导致两个循环都被那个设置时间长的定时影响了
    发表于 04-08 11:35

    为何国外工程师偏爱使用for(;;)来实现MCU死循环

    一位工程师发现,国外工程师在给demo在做死循环时用的是for(;;),而不是常用的while(1)。这仅仅是个人习惯的问题,还是有更深层次的含义?
    发表于 04-01 11:26 669次阅读
    为何国外工程师偏爱使用for(;;)来实现MCU<b class='flag-5'>死循环</b>?

    请问rtt线程内必须显式调用调度函数吗?

    我在一线程中 当创建对象失败的时候,会使用while(1)printf(“create obj failed!!\\n”) 方式进入死循环,这时候其他线程就不在运行了(表现是LCD上
    发表于 02-26 06:36

    arcgis中如何关联两个属性表

    在ArcGIS中,关联两个属性表是一重要的操作,可以通过此操作将两个表中的数据关联起来,以便进行分析和查询。下面是详细介绍如何在ArcGIS中实现属性表的关联。 首先,我们需要明确两个
    的头像 发表于 02-25 11:01 4317次阅读

    RTThread中main线程循环,如果main线程异常退出了,有什么办法可以监测到?

    RTThread中main线程循环,如果main线程异常退出了,有什么办法可以监测到?
    发表于 02-22 08:15