我之前在我们的项目里面解决了一个死锁的问题,然后我跟一个我的朋友聊了下,他让我深入研究下这个问题。大家也可以考虑想我的这个问题。

首先我们再看看什么是死锁?

什么是死锁

用个通俗的例子讲一讲死锁

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

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

我们看下面的代码

#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)
{//lockdo_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,除非代码上因为加锁存在的一些空指针。

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

单线程会导致死锁吗?相关推荐

  1. DllMain中不当操作导致死锁问题的分析——DllMain中要谨慎写代码(完结篇)

    之前几篇文章主要介绍和分析了为什么会在DllMain做出一些不当操作导致死锁的原因.本文将总结以前文章的结论,并介绍些DllMain中还有哪些操作会导致死锁等问题.(转载请指明出于breaksoftw ...

  2. DllMain中不当操作导致死锁问题的分析--加载卸载DLL与DllMain死锁的关系

    前几篇文章一直没有在源码级证明:DllMain在收到DLL_PROCESS_ATTACH和DLL_PROCESS_DETACH时会进入临界区.这个论证非常重要,因为它是使其他线程不能进入临界区从而导致 ...

  3. DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子2

    本文介绍使用Windbg去验证<DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子>中的结论,调试对象是文中刚开始那个例子.(转载请指明出于breakso ...

  4. DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子

    有了前面两节的基础,我们现在切入正题:研究下DllMain为什么会因为不当操作导致死锁的问题.首先我们看一段比较经典的"DllMain中死锁"代码.(转载请指明出于breaksof ...

  5. DllMain中不当操作导致死锁问题的分析--死锁介绍

    最近在网上看到一些关于在DllMain中不当操作导致死锁的问题,也没找到比较确切的解答,这极大吸引了我研究这个问题的兴趣.我花了一点时间研究了下,正好也趁机研究了下进程对DllMain的调用规律.因为 ...

  6. JAVA中如何确保N个线程可以访问N个资源,但同时又不导致死锁?

    ● JAVA中如何确保N个线程可以访问N个资源,但同时又不导致死锁? 考察点:死锁 参考回答: 使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁.因 ...

  7. 解决MySQL事务未提交导致死锁报错 避免死锁的方法

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/xuheng8600/article/d ...

  8. MySQL Innodb表导致死锁日志情况分析与归纳

    案例描述 在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下: (1)insert into back ...

  9. php 批量更新死锁,php – 在尝试获取锁定时,哪个查询导致死锁;尝试重新启动事务...

    我无法弄清楚哪个Query在尝试获取锁定时导致死锁;尝试重新启动事务. 我的 mysql包装器有以下几行 if (mysql_errno($this->conn) == 1213) { $thi ...

最新文章

  1. Linux命令行使用matplotlib,报错_tkinter.TclError: no display name and no $DISPLAY environment variable问题解决
  2. JavaScript——易班优课YOOC课群在线测试自动答题解决方案(十六)利用PC端和移动端BUG
  3. LeetCode 5178. 四因数
  4. 【MatConvNet】配置GPU
  5. 东芝正式退出笔记本电脑业务!
  6. 如何使用 AOP 和自定义注解?
  7. Bug(七)—— error LNK2019:无法解析的外部符号
  8. 181212每日一句
  9. 哲学的终极解释:48张图了解48种主义
  10. GIF动图制作全攻略!不用PS简单快速制作GIF动图!
  11. python websockets 网络聊天室V1
  12. MATLAB制作扇形图及颜色调配
  13. 小红书KOC和KOL这两者怎样进行投放?
  14. vscode里面如何配置库_怎么为vscode添加库文件_编程开发工具
  15. 基于SSM的垃圾分类管理系统-含论文【数据库设计、论文、源码、开题报告】
  16. 仿六间房 新浪秀场网页视频聊天室 网页视频直播系统
  17. 饿了么 (Element)的 日历(Calendar)组件 自定义
  18. 带进度条的x5WebView
  19. Java字符串去重的几种实现
  20. Ubuntu正确卸载cuda11.0 | 安装cuda10.1、cuDNN

热门文章

  1. Strus2中关于ValueStack详解
  2. 火狐浏览器Firefox如何使用插件,火狐有哪些好用的插件
  3. spring MVC中页面添加锚点
  4. SEO的十种赚钱方式
  5. Linux之yum安装lamp环境
  6. C语言里最基础的关键字
  7. 多股回测(backtrader+quantstats+akshare)
  8. rs232读取智能电表_三相电表怎么看度数 怎么计算总电量
  9. C++基础之this指针的详解
  10. mysql c语言教程,C语言调用mysql快速教程(精华篇).pdf