死锁产生的各种情况

先了解下什么叫做死锁:
一个或多个变量被可执行程序的其中一个线程锁住了,其他线程都无法访问这个资源,被阻塞在对这个资源访问前,但是锁住这个资源的线程本身也被锁住了,它也被阻塞在对这个资源访问的前面。
那么为什么锁住资源的线程本身也被锁住了呢,这就是死锁产生的原因,比如这个线程锁住了资源,但是离开时忘记解锁,因此下次再来访问时也被阻塞住了。
下面是一些死锁的情况,以下是伪代码:
1,加锁之后忘记解锁

void funcA()
{
    for (int i = 0; i < 10; i++)
    {
        //第二次循环到这得时候就会被锁住
        pthread_mutex_lock(&mutex);
        .........
        //忘记解锁,下面进入下一次循环
    }
}
void funcA()
{
        //第二次循环到这得时候就会被锁住
        pthread_mutex_lock(&mutex);
        .........
        //忘记解锁,下面进入下一次循环
			 if(...)
			 {
			 ...
			 return NULL;//从这里返回后,依然没有解锁就离开了,会阻塞住其他线程,本线程下次再次访问这些被锁住的资源也会被锁住,这是锁的机制,一把锁,如果没有解锁,即使是加锁的线程也不能再次加锁。
			 }
			 pthread_mutex_unlock(&mutex);
}

2.重复加锁

void funcA()
{
        //第二次循环到这得时候就会被锁住
        pthread_mutex_lock(&mutex);
        .........
        .........
        .........
        pthread_mutex_lock(&mutex);//重复加锁,这时会阻塞在这里
        ........
         pthread_mutex_unlock(&mutex);
}

还有隐藏的比较深的

void funcB()
{
        //第二次循环到这得时候就会被锁住
        pthread_mutex_lock(&mutex);
        .........
        .........
        .........
        ........
         pthread_mutex_unlock(&mutex);
}
void funcA()
{
        //第二次循环到这得时候就会被锁住
        pthread_mutex_lock(&mutex);
        .........
        .........
        .........
        funcB();//在这里调用,使得重复加锁,会阻塞在funcB()的加锁代码语句前
        ........
         pthread_mutex_unlock(&mutex);
}

以上两种情况可以归结为犯了锁的一个机制,因此被阻塞:一把锁,如果没有解锁,所有线程即使是加锁的线程本身,也不能再次加锁,只会被阻塞。
3,资源比较多,互相访问
有线程A,B
资源int_a,int_b
A加锁了int_a
B加锁了int_b
之后:
A去访问了int_b,这时B也访问了int_a。
因为int_b被B加锁了,所以A在访问它之前被阻塞住了
因为int_a被A加锁了,所以B在访问它之前也被阻塞住了
因为A,B都被阻塞住了,因此他们都不能解锁自己锁住的资源。
它两线程就这么互相绷住了…

那么怎么防止死锁呢,加锁后一定要记得解锁,避免重复加锁。
加锁函数可以使用trylock,这个函数会尝试加锁,如果无法加上也不会阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

、、、、南山小雨、、、、

分享对你有帮助,打赏一下吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值