多线程死锁

1. 产生死锁的原因主要是:
(1) 因为系统资源不足
(2) 进程运行推进的顺序不合适
(3) 资源分配不当等

2. 线程死锁产生的必要条件:

1互斥条件:一个资源每次只能被一个进程使用。 (资源固有属性,无法破坏)

2请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 (一次性将资源全部分配)

3不可剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。 资源只能由占有者自愿释放;(使用线程优先级,超时机制)

4循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。(资源有序分配)

 

避免死锁,

(1) 等待某个资源时,使用超时机制

(2) 采用消息通信的通信机制; 

 

 

产生死锁的情况:

  1)忘记释放锁

  void data_process()
  {
      EnterCriticalSection();

      if(/* error happens */)
          return;

      LeaveCriticalSection();
  }

 

  2)单线程重复申请锁(并不会引起死锁,EnterCriticalSecton和LeaveCriticalSection需要成对使用;即Enter了几次,必须Leave几次)

  void sub_func()
  {
      EnterCriticalSection();
      do_something();
      LeaveCriticalSection();
  }

  void data_process()
  {
      EnterCriticalSection();
      sub_func();
      LeaveCriticalSection();
  }  

 

  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);
  }

 

  4)环形锁申请

  假设有A、B、C、D四个人在一起吃饭,每个人左右各有一只筷子。所以,这其中要是有一个人想吃饭,他必须首先拿起左边的筷子,再拿    起右边的筷子。现在,我们让所有的人同时开始吃饭。那么就很有可能出现这种情况。每个人都拿起了左边的筷子,或者每个人都拿起了右边的筷子,为了吃饭,他们现在都在等另外一只筷子。此时每个人都想吃饭,同时每个人都不想放弃自己已经得到的一那只筷子。所以,事实上大家都吃不了饭。

 

其他情况:假设执行情况为process1,process2,process3;

  void data_process1()
  {

    EnterCriticalSection(&cs1);

    dosomething();

  }

 

  void data_process2()
  {

    LeaveCriticalSection(&cs1);

    dosomething();

  }

 

   void data_process3()
  {

    EnterCriticalSection(&cs1);

    dosomething();

    LeaveCriticalSection(&cs1);

  }

现象:

  1. 由于process2释放了不属于自己的临界区;导致process3永远得不到执行机会(死锁);

  2. 修改临界区为互斥量时,process2并不能释放互斥量;

 

 

 

 

 

 

 

 

   

 

posted @ 2015-04-19 22:34  hy1hy  阅读(209)  评论(0编辑  收藏  举报