码迷,mamicode.com
首页 > 编程语言 > 详细

多线程编程之线程死锁问题

时间:2017-12-08 20:41:30      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:编程经验   释放   检查   应该   自己   tle   app   等待资源   工程   

在多线程编程中,除了要解决数据访问的同步与互斥之外,还需要解决的重要问题就是多线程的死锁问题。所谓死锁: 是指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外部处理作用,它们都将无限等待下去。

一、死锁原因与形成条件

  死锁形成的原因:

  1. 系统资源不足
  2. 进程(线程)推进的顺序不恰当;
  3. 资源分配不当

  死锁形成的条件:

  1. 互斥条件:所谓互斥就是进程在某一时间内独占资源。
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

  从编程经验上来讲,形成死锁的一般原因有以下几种:

  1. 个人使用锁的经验差异。
  2. 程序模块使用锁的差异。
  3. 工程代码版本之间的差异。
  4. 工程代码分支之间的差异。
  5. 修改代码和重构代码带来的差异。

二、常见死锁形成的场景

  死锁形成的常见情况有以下几种:

2.1 忘记释放锁

技术分享图片
void data_process()
{
    EnterCriticalSection();

    if(/* error happens, forget LeaveCriticalSection */)
        return;

    LeaveCriticalSection();
}
技术分享图片

 2.2 单线程重复申请锁

技术分享图片
void sub_func()
{
    EnterCriticalSection();
    do_something();
    LeaveCriticalSection();
}

void data_process()
{
    EnterCriticalSection();
    sub_func();
    LeaveCriticalSection();
}
技术分享图片

 2.3 多线程多锁申请

技术分享图片
void data_process1()
{
    EnterCriticalSection(&cs1);  // 申请锁的顺序有依赖
    EnterCriticalSection(&cs2);
    do_something1();
    LeaveCriticalSection(&cs2);
    LeaveCriticalSection(&cs1);
}

void data_process2()
{
    EnterCriticalSection(&cs2);  // 申请锁的顺序有依赖
    EnterCriticalSection(&cs1);
    do_something2();
    LeaveCriticalSection(&cs1);
    LeaveCriticalSection(&cs2);
}
技术分享图片

 2.4 环形锁申请

/* 多个线程申请锁的顺序形成相互依赖的环形:
*             A   -  B
*             |      |
*             C   -  D
*/

 三、死锁的避免策略

  死锁的代价是非常大的,有时候很难检测排查,因此需要在编程过程中尽可能的避免发生死锁。编程中为了避免死锁应该遵循如下策略

  1. 在编写多线程程序之前,首先编写正确的程序,然后再移植到多线程。
  2. 时刻检查自己写的程序有没有在跳出时忘记释放锁。
  3. 如果自己的模块可能重复使用一个锁,建议使用嵌套锁
  4. 对于某些锁代码,不要临时重新编写,建议使用库里面的锁,或者自己曾经编写的锁。
  5. 如果某项业务需要获取多个锁,必须保证锁的按某种顺序获取,否则必定死锁。
  6. 编写简单的测试用例,验证有没有死锁。
  7. 编写验证死锁的程序,从源头避免死锁。

多线程编程之线程死锁问题

标签:编程经验   释放   检查   应该   自己   tle   app   等待资源   工程   

原文地址:http://www.cnblogs.com/cyyljw/p/8006854.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!