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;
}
相关推荐
薛慕昭1 天前
嵌入式 C 语言猜大小游戏设计与实现
c语言·游戏
月光技术杂谈1 天前
实战:C驱动框架嵌入Rust模块的互操作机制与完整流程
c语言·开发语言·rust·ffi·跨语言·bindgen·互操作
合作小小程序员小小店1 天前
游戏开发,桌面%小游戏,贪吃蛇%demo,基于vs2022,c语言,easyX,无数据库
c语言·开发语言
WongKyunban1 天前
Linux中的线程是什么?
c语言
LaoZhangGong1231 天前
以太网HTTP数据包格式分析
c语言·stm32·网络协议·http·tcp·arp
lingggggaaaa2 天前
免杀对抗——C2远控篇&PowerShell&有无文件落地&C#参数调用&绕AMSI&ETW&去混淆特征
c语言·开发语言·笔记·学习·安全·microsoft·c#
口袋物联2 天前
设计模式之建造者模式在 C 语言中的应用(含 Linux 内核实例)
c语言·设计模式·建造者模式
切糕师学AI2 天前
位带操作(Bit-Banding)是什么?
c语言·arm·嵌入式开发·cortex-m·位带操作
学习路上_write2 天前
嵌入式系统bringup指南:软硬件调试
c语言·单片机·嵌入式硬件
say_fall2 天前
C语言编程实战:每日一题 - day7
c语言·开发语言