单线程会导致死锁你知道吗

 更新时间:2022年02月17日 17:34:36   作者:写代码的篮球球痴  
这篇文章主要为大家详细介绍了单线程会不会导致死锁,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

死锁从文字理论上说明的是两个线程,可以认为是两个人A和B,A在等待B完成某件事情,B又在等待A完成某件事情。

0422692999f4e81a98b7fe4c8a68e21e.png

那如果在代码中,单线程的某个函数,有没有可能导致死锁呢?

我们看下面的代码

#include<pthread.h>
#include<string.h>
#include<errno.h>
#include<stdio.h>
#include<unistd.h> 
pthread_mutex_t mutex;
int main()
{
    pthread_mutex_init(&mutex,NULL);
    printf("mutex init\n");
    pthread_mutex_lock(&mutex);
    printf("mutex lock#1\n");
    pthread_mutex_lock(&mutex);
    printf("mutex lock#2\n");
    pthread_mutex_unlock(&mutex);
    pthread_mutex_unlock(&mutex);
    pthread_mutex_destroy(&mutex);
    return 0; 
}

你看这样的代码会不会导致死锁呢?

线程在上锁后,又马上继续尝试上锁,这样的情况会不会存在?

类似这样的代码

int test_function(void)
{
  //lock
  do_something()
  if(x) return -1
  //unlock
}

在上锁后,然后下面会因为某种判断后退出,下一次进来后,又会进行上锁,这样的死锁是因为代码逻辑不正确导致的,也是很多新手常犯的问题。

如果是两个线程死锁的情况呢?

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t g_mutex_lock;
pthread_mutex_t g_mutex_lock2;
void *func1(void* args)
{
    printf("%s(),LINE=%d\n",__FUNCTION__,__LINE__);
    pthread_mutex_lock(&g_mutex_lock);
    sleep(1);
    pthread_mutex_lock(&g_mutex_lock2);
    printf("%s(),LINE=%d\n",__FUNCTION__,__LINE__);
    pthread_mutex_unlock(&g_mutex_lock);
    pthread_mutex_unlock(&g_mutex_lock2);
    return NULL;
}
void *func2(void* args)
{
    printf("%s(),LINE=%d\n",__FUNCTION__,__LINE__);
    pthread_mutex_lock(&g_mutex_lock2);
    sleep(1);
    pthread_mutex_lock(&g_mutex_lock);
    printf("%s(),LINE=%d\n",__FUNCTION__,__LINE__);
    pthread_mutex_unlock(&g_mutex_lock2);
    return NULL;
}
int main(void)
{
    int ret;
    pthread_t thread_1;
    pthread_t thread_2;
    printf("%s(),LINE=%d\n",__FUNCTION__,__LINE__);
    ret = pthread_mutex_init(&g_mutex_lock, NULL);
    if (ret != 0) {
        printf("mutex init failed\n");
        return -1;
    }
    ret = pthread_mutex_init(&g_mutex_lock2, NULL);
    if (ret != 0) {
        printf("mutex2 init failed\n");
        return -1;
    }
    pthread_create(&thread_1, NULL, func1, NULL);
    pthread_create(&thread_2, NULL, func2, NULL);
    pthread_join(thread_1, NULL);
    pthread_join(thread_2, NULL);
    pthread_mutex_destroy(&g_mutex_lock);
    pthread_mutex_destroy(&g_mutex_lock2);
    printf("%s(),LINE=%d\n",__FUNCTION__,__LINE__);
    return 0;
}

上面的代码比较典型了

线程1拿到1号锁后,开始等待2号锁,线程2拿到2号锁后,就开始等待一号锁。他们属于互相等待的情况。

代码输出

linux@ubuntu:/study$ gcc argc.c -pthread && ./a.out
main(),LINE=37
func1(),LINE=11
func2(),LINE=23

最后,线程出现死锁不会正常情况不会导致crash,除非代码上因为加锁存在的一些空指针。

所以单线程也是有可能导致死锁的。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!    

相关文章

  • Vscode中接入Deepseek的实现

    Vscode中接入Deepseek的实现

    本文主要介绍了Vscode中接入Deepseek的实现,包括登录Deepseek官网、申请APIKEY、安装和配置VSCode插件,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02
  • 关于C++多重继承下虚表结构的问题

    关于C++多重继承下虚表结构的问题

    这篇文章主要介绍了C++ 多重继承下虚表结构的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • C++中图片重命名实现代码

    C++中图片重命名实现代码

    这篇文章主要介绍了C++中图片重命名实现代码,需要的朋友可以参考下
    2017-05-05
  • 深入理解C++中std::chrono库的使用

    深入理解C++中std::chrono库的使用

    在程序设计中,时间管理是一个核心概念,它不仅关系到程序的效率和性能,而且直接影响用户体验,C++作为一门高效的编程语言,提供了std::chrono库,用于精确地处理和计算时间,下面就跟随小编一起学习一下std::chrono库的使用吧
    2023-12-12
  • C语言通过三种方法实现属于你的通讯录

    C语言通过三种方法实现属于你的通讯录

    本文将实现一个通讯录,来实现人员的增删插改功能。文中通过三种形式来实现用户的增删插改,其实也就是一点点的优化版本,从静态的实现,到动态的实现,最后以文件的形式来完成,请大家和我一起往下看吧
    2022-11-11
  • C++实现N个骰子的点数算法

    C++实现N个骰子的点数算法

    这篇文章主要介绍了C++实现N个骰子的点数算法,用两种方法实现了该功能,是非常实用的技巧,需要的朋友可以参考下
    2014-09-09
  • C++超详细实现二叉树的遍历

    C++超详细实现二叉树的遍历

    本章将会详细讲解二叉树遍历的四种方式,分别为前序遍历、中序遍历、后续遍历和层序遍历。在学习遍历之前,会先带大家回顾一下二叉树的基本概念
    2022-05-05
  • C++中vector迭代器失效与深浅拷贝问题详析

    C++中vector迭代器失效与深浅拷贝问题详析

    迭代器失效就是迭代器底层对应指针所指向的空间倍销毁了,导致使用了一块已经被释放了的空间,下面这篇文章主要给大家介绍了C++中vector迭代器失效与深浅拷贝问题的相关资料,需要的朋友可以参考下
    2023-01-01
  • Qt自定义表头实现过滤功能的方法

    Qt自定义表头实现过滤功能的方法

    这篇文章主要个给大家介绍了关于Qt自定义表头实现过滤功能的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Qt具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • C++实现顺序表的常用操作(插入删出查找输出)

    C++实现顺序表的常用操作(插入删出查找输出)

    实现顺序表的插入,删除,查找,输出操作在C语言中经常用到。下面小编给大家整理实现代码,一起看下吧
    2016-08-08

最新评论