【Linux系统编程】死锁现象

        当多个线程中为了保护多个共享资源而使用了多个互斥锁,如果多个互斥锁使用不当,就可能造成,多个线程一直等待对方的锁释放,这就是死锁现象。

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<time.h>

pthread_mutex_t mtx1;
pthread_mutex_t mtx2;

void* thread1(void* arg) {
    printf("子线程获取mtx1中。。。。\n");
    pthread_mutex_lock(&mtx1);
    printf("子线程获取mtx1成功\n");
    sleep(3);

    printf("子线程获取mtx2中。。。。\n");
    pthread_mutex_lock(&mtx2);
    printf("子线程获取mtx2成功\n");

    pthread_mutex_unlock(&mtx2);
    pthread_mutex_unlock(&mtx1);

    
}

int main(int argc, char* argv[])
{
    //初始化一个互斥量
    pthread_mutex_init(&mtx1, NULL);
    pthread_mutex_init(&mtx2, NULL);

    pthread_t tids;
    pthread_create(&tids, NULL, thread1, NULL);


    printf("主线程获取mtx2中。。。。\n");
    pthread_mutex_lock(&mtx2);
    printf("主线程获取mtx2成功\n");
    sleep(3);

    printf("主线程获取mtx1中。。。。\n");
    pthread_mutex_lock(&mtx1);
    printf("主线程获取mtx1成功\n");
    
    pthread_mutex_unlock(&mtx2);
    pthread_mutex_unlock(&mtx1);

    pthread_mutex_destroy(&mtx1);
    pthread_mutex_destroy(&mtx2);
    return 0;
}

死锁了

死锁产生的四个必要条件:

​    ●互斥条件:资源只能同时被一个线程占用

​    ●持有并等待条件:线程1已经持有资源A,可以申请持有资源B,如果资源B已经被线程2持有,这时线程1持有资源并等待资源B

​    ●不可剥夺条件:一个线程持有资源,只能自己释放后其他线程才能使用。其他线程不能强制收回该资源

​    ●环路等待条件:多个线程互相等待资源,形成一个环形等待链

避免死锁:破坏其中一个必要条件就可以避免死锁

常用的方法如下:

​    ●锁的粒度控制:破坏请求与保持条件,尽可能减少持有锁的时间,降低发生死锁的可能性

​    ●资源有序分配:破坏环路等待条件,规定线程使用资源的顺序,按规定顺序给资源加锁

​    ●重试机制:破坏不可剥夺条件,如果尝试获取资源失败,放弃已持有的资源后重试

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<time.h>
//资源有序分配,破坏环路等待条件,规定线程使用资源的顺序,按规定顺序给资源加锁
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;

void* thread1(void* arg) {
    printf("子线程获取mtx1中。。。。\n");
    pthread_mutex_lock(&mtx1);
    printf("子线程获取mtx1成功\n");
    sleep(3);

    printf("子线程获取mtx2中。。。。\n");
    pthread_mutex_lock(&mtx2);
    printf("子线程获取mtx2成功\n");

    pthread_mutex_unlock(&mtx2);
    pthread_mutex_unlock(&mtx1);

}

int main(int argc, char* argv[])
{
    //初始化一个互斥量
    pthread_mutex_init(&mtx1, NULL);
    pthread_mutex_init(&mtx2, NULL);

    pthread_t tids;
    pthread_create(&tids, NULL, thread1, NULL);

    printf("主线程获取mtx1中。。。。\n");
    pthread_mutex_lock(&mtx1);
    printf("主线程获取mtx1成功\n");
    sleep(3);

    printf("主线程获取mtx2中。。。。\n");
    pthread_mutex_lock(&mtx2);
    printf("主线程获取mtx2成功\n");
    
    pthread_mutex_unlock(&mtx2);
    pthread_mutex_unlock(&mtx1);

    sleep(10);
    pthread_mutex_destroy(&mtx1);
    pthread_mutex_destroy(&mtx2);
    return 0;
}

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<time.h>
//重试机制:破坏不可剥夺条件,如果尝试获取资源失败,放弃已持有的资源后重试
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;

void* thread1(void* arg) {
    printf("子线程获取mtx1中。。。。\n");
    while(1) {
        pthread_mutex_lock(&mtx1);
        printf("子线程获取mtx1成功\n");
        sleep(3);

        printf("子线程获取mtx2中。。。。\n");
        int ret = pthread_mutex_trylock(&mtx2);
        if(ret != 0 && ret == EBUSY) {
            pthread_mutex_unlock(&mtx1);
            printf("子线程释放mtx1\n");
            sleep(1);
            continue;
        }
        printf("子线程获取mtx2成功\n");
        pthread_mutex_unlock(&mtx2);
        pthread_mutex_unlock(&mtx1);
        break;
    }
}

int main(int argc, char* argv[])
{
    //初始化一个互斥量
    pthread_mutex_init(&mtx1, NULL);
    pthread_mutex_init(&mtx2, NULL);

    pthread_t tids;
    pthread_create(&tids, NULL, thread1, NULL);
    while(1) {
        printf("主线程获取mtx2中。。。。\n");
        pthread_mutex_lock(&mtx2);
        printf("主线程获取mtx2成功\n");
        sleep(3);

        printf("主线程获取mtx1中。。。。\n");
        int ret = pthread_mutex_trylock(&mtx1);
        if(ret != 0 && ret == EBUSY) {
            pthread_mutex_unlock(&mtx2);
            printf("主线程释放mtx2\n");
            sleep(1);
            continue;
        }
        printf("主线程获取mtx1成功\n");
        pthread_mutex_unlock(&mtx2);
        pthread_mutex_unlock(&mtx1);
        break;
    }
    sleep(10);
    pthread_mutex_destroy(&mtx1);
    pthread_mutex_destroy(&mtx2);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值