首页 > 系统相关 >[ Linux ] 死锁以及如何避免死锁

[ Linux ] 死锁以及如何避免死锁

时间:2022-12-23 13:03:48浏览次数:56  
标签:Linux 避免 死锁 线程 pthread mutexB mutex mutexA

1.什么是死锁?

死锁

  • 死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所占用不会释放的资源而处于的一种永久等待的状态。

2.模拟死锁情况

我们使用多线程模拟一个死锁的情况。

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <mutex>

using namespace std;

pthread_mutex_t mutexA = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexB = PTHREAD_MUTEX_INITIALIZER;
void* startRoutine1(void* args)
{
while(true)
{
pthread_mutex_lock(&mutexA);
sleep(1);
pthread_mutex_lock(&mutexB);
cout<<"我是线程1,我的tid"<<pthread_self()<<endl;
pthread_mutex_unlock(&mutexB);
pthread_mutex_unlock(&mutexA);
}

}

void* startRoutine2(void* args)
{
while(true)
{
pthread_mutex_lock(&mutexB);
sleep(1);
pthread_mutex_lock(&mutexA);
cout<<"我是线程2,我的tid"<<pthread_self()<<endl;
pthread_mutex_unlock(&mutexB);
pthread_mutex_unlock(&mutexA);
}
}


int main()
{
pthread_t t1,t2;

pthread_create(&t1,nullptr,startRoutine1,nullptr);
pthread_create(&t2,nullptr,startRoutine2,nullptr);

pthread_join(t1,nullptr);
pthread_join(t2,nullptr);
return 0;
}

当上面这段程序运行起来时,线程1和线程2会同时调用各自的startRountine函数,由于mutexA和mutexB均为临界资源只有一份,而在程序中,线程1会先申请mutexA,线程2会先申请mutexB,而当他们申请结束时都会等待1秒(这里等待一秒是确保两个线程各自占有一把锁),一秒休眠结束后,当线程1想要申请mutexB时,由于mutexB已经被线程2占有且未释放,因此线程1将阻塞等待mutexB的释放;同理,线程2也会阻塞等待mutexA。此时,各线程均占有不会释放的资源mutex,并且互相申请了其他线程所占用不会释放的资源而除以一种永久等待的状态。我们把这种状态就称为死锁。当程序运行起来时,我们也能看到程序并没有什么打印结果.....

我们使用监控脚本查看3个线程任然在运行之中

while :; do ps -aL | grep mythread ; sleep 1;echo "---------------";done


3.死锁四个必要条件

死锁的必要条件:死锁情况一旦发生,这四个条件一定都要满足。如果有一个没有产生,那死锁的条件便不成立。

  1. 互斥条件:一个资源每次只能被一个执行流使用
  2. 请求与保持条件:一个执行流因请求资源而阻塞时,对已获得的资源保持不败
  3. 不剥夺条件:一个执行流已获得的资源,在未使用完之前,不能强行剥夺
  4. 循环等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系


4.避免死锁的方法

  • 破坏死锁的四个必要条件
  • 加锁顺序一致
  • 避免锁未释放的场景
  • 资源一次性分配


5.避免死锁的算法

银行家算法(了解为主)

我们在当时将锁的时候,查看过pthread_mutex_lock和pthread_mutex_unlock函数,我们也使用了,那么大家还记不记得其中还有一个trylock。这个函数就是用来尝试申请,如果是安全序列则会正式分配,否则不会分配。

核心思想:

银行家算法是一种最有代表性的避免死锁的算法。在避免​​死锁​​方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。


标签:Linux,避免,死锁,线程,pthread,mutexB,mutex,mutexA
From: https://blog.51cto.com/xingyuli/5965370

相关文章

  • 文件目录结构、文件命名规范、文件系统结构、linux应用程序的组成、绝对路径和相对路
    文件目录结构文件和目录被组织成一颗倒置的树状结构文件系统从根开始,“/”文件名称严格区分大小写隐藏文件以"."开头路径的分隔符为"/"文件命名规范文件字符最长为255个字符......
  • Linux服务器安装python3.7环境
    安装python3.7依赖yum-yinstallzlib-develbzip2-developenssl-develncurses-develsqlite-develreadline-develtk-develgdbm-develdb4-devellibpcap-develxz-......
  • linux 命令使用5--mpstat
    简介:    mpstat是MultiprocessorStatistics的缩写,是实时系统监控工具。其报告与CPU的一些统计信息,这些信息存放在/proc/stat文件中。在多CPUs系统里,其不但能查看......
  • Linux常用命令
    常用命令书写命令要用空格分开,一个或多个都可以ping是命令符www.baidu是参数如果不知道要用的命令可以借助Linux命令大全help找命令的帮助whereis查询命令的位置file查看文......
  • Linux 常用命令总结
    Linux常用命令总结作者:Grey原文地址:博客园:Linux常用命令总结CSDN:Linux常用命令总结本文基于的Linux环境是CentOS7,主要是日常使用的一些命令,持续更新中……......
  • 解决RockyLinux和Centos Stream 9中firefox无法播放HTML视频问题
    如题在测试两种centos后续系统时,发现firefox无法播放HTML视频问题。经过一番折腾找到了解决的办法,具体解决如下:首先下载VLC$sudoyuminstallvlc而后重启浏览器就可......
  • Linux系统入门-Shell命令
    linux中的shellLinux中的shell,是指一个面向用户的命令接口,表现形式就是一个可以由用户录入的界面,这个界面也可以反馈运行信息。shell在Linux中的存在形式由于Linux不同于Win......
  • Linux: NetworkManager
     permissions:允许非root用户控制网络grantpermissionnmclicmodifyconvoluteconnection.permissions'user:intrinsic,gdm' disablepolkit/etc/NetworkM......
  • 分享巧记Linux命令的方法
    最近有些学弟经常私信问我说,他们自己是Linux方面的小白,对于Linux的命令了解十分的少,虽然每次跟着我推荐的学习视频教程可以进行操作,但是离开了视频,就又是两眼抓瞎,什么也想......
  • Linux readonly
    1.概念readonly在shell脚本中,用来标记变量是只读的,后续执行过程中就不能对其值进行改变,这个用来定义一些常量类的变量.如果对其进行重新赋值,会提示错误[root@localhost......