快捷搜索: 王者荣耀 脱发

递归互斥量解决死锁问题

一、递归互斥量

一般情况下,我们在同一个线程中对同一个互斥量加两次锁,就会死锁(自我死锁)。如果将互斥量类型属性设置为递归类型 PTHREAD_MUTEX_RECURSIVE 就不会出现此问题。

递归互斥量内部维护着一个计数器,当互斥量未上锁时,计数器值为 0。只有计数器为 0 的情况下,线程才能够获得锁。只有获得锁的线程,才能持续对互斥量加锁,每加一次锁,计数器的值加 1,每解一次锁,计数器的值减 1.

二、 死锁的概念

日常生活的死锁:我们只招有工作经验的人!我没有工作经验怎么办?那你就去找工作啊! 假设有2个互斥量M1、M2,2个任务A、B: A获得了互斥量M1 B获得了互斥量M2 A还要获得互斥量M2才能运行,结果A阻塞 B还要获得互斥量M1才能运行,结果B阻塞 A、B都阻塞,再无法释放它们持有的互斥量 死锁发生!

三、自我死锁

假设这样的场景: 任务A获得了互斥锁M 它调用一个库函数 库函数要去获取同一个互斥锁M,于是它阻塞:任务A休眠,等待任务A来释放互斥锁! 死锁发生!

四、用递归互斥量解决死锁问题

两个任务经过精细设计,运行流程如下所示: A:任务1优先级最高,先运行,获得递归锁 B:任务1阻塞,让任务2得以运行 C:任务2运行,看看能否获得别人持有的递归锁:不能 D:任务2故意执行"give"操作,看看能否释放别人持有的递归锁:不能 E:任务2等待递归锁 F:任务1阻塞时间到后继续运行,使用循环多次获得、释放递归锁 递归锁在代码上实现了:谁持有递归锁,必须由谁释放。

经验分享 程序员 微信小程序 职场和发展