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

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

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

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

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

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

 

避免死锁,

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

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

产生死锁的情况:
  1)忘记释放锁
  void data_process()
  {
      EnterCriticalSection();      if(/* error happens */)
          return;      LeaveCriticalSection();
  } 
(并不会引起死锁,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);
  }
现象:

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

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