C语言线程之死锁

死锁概念

**死锁(Deadlock)**由于某种逻辑问题,导致等待一个永远无法获得的资源的困境

产生死锁的原因

  • 连续多次上锁
  • 忘记解锁
  • 线程未解锁就被取消
示例1 连续上锁
cpp 复制代码
#include<stdio.h>
#include<pthread.h>
#include <unistd.h>

// 定义互斥锁
pthread_mutex_t mutex;

int global = 0;

void *fun()
{
    // 上锁
    pthread_mutex_lock(&mutex);
    pthread_mutex_lock(&mutex);    //连续上锁
    global = 10;
    printf("global=%d\n",global);
    //解锁
    pthread_mutex_unlock(&mutex);    

}

int main(int argc, char const *argv[])
{
    // 初始化互斥锁
    pthread_mutex_init(&mutex,NULL);

    pthread_t pid;
    pthread_create(&pid,NULL,fun,NULL);

    pthread_join(pid,NULL);
    return 0;
}
示例2 忘记解锁
cpp 复制代码
#include<stdio.h>
#include<pthread.h>
#include <unistd.h>

// 定义互斥锁
pthread_mutex_t mutex;

int global = 0;

void *fun()
{
    // 连续上锁
    pthread_mutex_lock(&mutex);
    global = 10;
    printf("global=%d\n",global);
    //pthread_mutex_unlock(&mutex);    //忘记解锁

}

int main(int argc, char const *argv[])
{
    // 初始化互斥锁
    pthread_mutex_init(&mutex,NULL);

    pthread_t pid;
    pthread_create(&pid,NULL,fun,NULL);


    pthread_join(pid,NULL);
    return 0;
}
示例三 线程未解锁就被取消
cpp 复制代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// 定义互斥锁
pthread_mutex_t mutex;

int global = 0;

void *fun()
{
    // 连续上锁
    pthread_mutex_lock(&mutex);
    // pthread_mutex_lock(&mutex);
    global = 100;
    while (global--)
    {
        printf("global=%d\n", global);
    }

    pthread_mutex_unlock(&mutex); // 忘记解锁
}

int main(int argc, char const *argv[])
{
    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    pthread_t pid;
    pthread_create(&pid, NULL, fun, NULL);

    // 未解锁就取消线程
    sleep(5);
    pthread_cancel(pid);

    pthread_join(pid, NULL);
    return 0;
}

解决死锁的方法

线程取消历程函数

压栈

pthread_cleanup_push(void fun(void * arg), 参数);

出栈

ptread_cleanup_pop(int arg);

arg 0 不执行历程函数

1 执行历程函数

示例4 避免死锁
cpp 复制代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// 定义互斥锁
pthread_mutex_t mutex;

int global = 0;

void rount()
{
    pthread_mutex_unlock(&mutex);
}

void *fun()
{
    // 压栈
    pthread_cleanup_push(rount,NULL);

    // 连续上锁
    pthread_mutex_lock(&mutex);
    // pthread_mutex_lock(&mutex);
    global = 100;
    while (global--)
    {
        sleep(1);
        printf("global=%d\n", global);
    }

    pthread_mutex_unlock(&mutex); // 忘记解锁

    pthread_cleanup_pop(1);

}

int main(int argc, char const *argv[])
{
    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    pthread_t pid;
    pthread_create(&pid, NULL, fun, NULL);

    // 未解锁就取消线程
    sleep(5);
    pthread_cancel(pid);

    pthread_join(pid, NULL);
    return 0;
}
相关推荐
钢琴上的汽车软件19 分钟前
C 语言中const与指针:三种常见写法辨析
c语言·指针和const
ZK_H39 分钟前
嵌入式c语言——关键字其6
c语言·开发语言·计算机网络·面试·职场和发展
ambition202421 小时前
从暴力搜索到理论最优:一道任务调度问题的完整算法演进历程
c语言·数据结构·c++·算法·贪心算法·深度优先
cmpxr_1 小时前
【C】原码和补码以及环形坐标取模算法
c语言·开发语言·算法
yashuk2 小时前
C语言实现PAT练习及算法学习笔记,还有SQLite介绍
c语言·sqlite·开源项目·算法学习·pat练习
ACP广源盛139246256732 小时前
破局 Type‑C 切换器痛点@ACP#GSV6155+LH3828/GSV2221+LH3828 黄金方案
c语言·开发语言·网络·人工智能·嵌入式硬件·计算机外设·电脑
爱编码的小八嘎3 小时前
C语言完美演绎7-10
c语言
hhh3u3u3u5 小时前
Visual C++ 6.0中文版安装包下载教程及win11安装教程
java·c语言·开发语言·c++·python·c#·vc-1
泛凡(Linyongui)5 小时前
PY32F002B实践之二--宠物腹背理疗仪项目介绍及头文件解析
c语言·keil·py32·32位单片机·腹背理疗仪项目实践
网域小星球7 小时前
C 语言从 0 入门(十四)|文件操作:读写文本、保存数据持久化
c语言·开发语言·文件操作·fopen·fprintf