周一的时候,程序中可能发生死锁的情况,而且发生死锁也是偶然的,时而发生,而且数据量大的时候发生的比较多一点,断线后重连的时候发生的概率也大一点。
1、开始的时候怀疑是Terabit的使用中关于Read和Write的时候发生死锁,所以将程序中两个重要的锁的锁定范围缩小到最小,而且对于Protocol对象使用了引用计数,以便在向Protocol中写入数据的时候不至于将Protocol锁住,但是现象还是发生。
2、后来在vs中查看锁对象的占用,发现之所以线程锁住,是由于Terabit在释放Message_Block的时候等待了。而且根据提示是两个Message_Block的线程相互等待,经过对Terabit的代码分析发现,在Terabit中写消息的时候会将接受到底Message_Block串联起来(cont函数调用),然后在将他们发送完毕后依次调用每个Message_Block的release函数,将每个Message_Block释放掉。至此,联系到上面的对Message_Block的锁机制,发现可能的一个死锁情况:
a) 现在锁队列中两个锁L1和L2
b) 一个发送线程中的两个Message_Block为M11,M12,程序中为他们分配的锁为L1,L2
c) 另一个发送线程中的两个Message_Block为M21,M22,程序中为他们分配的锁为L2,L1
d) 则在b线程析构Message_Block的时候,会依次获取L1,L2
e) 则在c线程析构Message_Block的时候,会依次获取L2,L1
f) 上面两个线程就发生了死锁,并且无法自行解开