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;
}
相关推荐
彭刷子9 小时前
[c语言]简单的进行多次计算的+-*/计算机
c语言·学习
我是一只菜菜9 小时前
Pointer--Learing MOOC-C语言第九周指针
c语言·开发语言
蒜鸟~蒜鸟10 小时前
基于 C 语言的网络单词查询系统设计与实现(客户端 + 服务器端)
c语言·网络·oracle
小莞尔12 小时前
【51单片机】【protues仿真】基于51单片机音乐盒(8首歌曲)系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
智者知已应修善业12 小时前
【51单片机三路抢答器定时器1工作1外部中断1】2022-11-24
c语言·经验分享·笔记·嵌入式硬件·51单片机
j_xxx404_13 小时前
数据结构:单链表的应用(力扣算法题)第二章
c语言·数据结构·算法·leetcode
劲镝丶13 小时前
51单片机的电子音乐盒 (详细教程)
c语言·c++·单片机·嵌入式硬件·51单片机
Natsume171014 小时前
音视频开发入门:FFmpeg vs GStreamer,新手该如何选择?
c语言·c++·ffmpeg·音视频·webrtc·实时音视频·视频编解码
studytosky15 小时前
C语言数据结构之双向链表
c语言·数据结构·c++·算法·链表·c