Some useful tips about developing multi-threading applications 
 
这四五个月以来主要做KSP的开发,主要的难点是多线程同步。到现在为止,已经积累了不少开发多线程的经验,尤其是调试多线程和一些多线程开发经验。 下面的tips全部来自开发过程中遇到的问题。
 
1。在写MFC的DLL时千万要小心。最好不要在InitInstance中调用一些你不知道它具体会做什么的初始化操作,如果那些初始化操作需要创建一个新的线程,并且需要等待新创建的线程结束时,会造成死锁。
因为InitInstance是在DllMain中被调用,而新创建的线程在调用线程入口函数前,在kernel中需要调用当前进程中的所有DllMain,
但是InitInstance所在线程,也就是DllMain所在线程在等待新创建的线程结束,所以这里造成死锁。新创建的线程会在Kernel中卡住,线程入口函数无法被执行。
为了这个问题,我花了两天时间。真是shit。我为一个新硬件写了一个KSP,而那个调用我的KSPl的程序是个用MFC写的控制面板程序(DLL)。它在InitInstance中调用我KSP的初始化函数,这个初始化函数中要创建一个线程,并且等待它结束,所以造成死锁。因为那个控制面板程序是很早以前写的。我一直没想到是控制面板程序的问题,一直在我的KSP中找原因。
如果你发现你的线程入口函数无法执行,请首先排除是不是这个原因。
 
2.在多线程中使用GUI函数要尤其小心。比如EnableWindow这个函数,它会导致线程切换,切换到目的窗口所在的线程。如果当前的线程获取了一个Mutex或者CriticalSection,而窗口所在线程正在Wait这些资源,那么就会造成死锁。
为了这个问题,我也花了一个下午,最后加班到晚上8点还没搞定(当时还不会用4种提到的windbg),然后回去之前忘记打卡,还被罚了100元,真是郁闷。第二天一早才搞定。
 
3。尽量使保护区域(用mutex或者CriticalSection)中执行的代码最少。
 
尤其不要执行一些会引起线程调度(这个同2)或者需要Acquire mutex或者CriticalSection的函数。这样很容易造成死锁。这个问题我碰到了好多次了。
 
4。调试多线程死锁的最好工具(起码我目前知道的)是WinDbg。
 
将Windbg attach到死锁的进程,它就它可以列出当前进程的所有的线程,并且可以查看堆栈,如果你有symbol的话,可以查看具体的函数名,如果有代码的话,可以查看源码。并且在没有源码的机器上可以先将进程dump出来,然后在有symbol和源码的机器上面进行分析。以前分析死锁都是用原始的日志,为了一个死锁往往要加入n多的日志,并花不少时间来分析,一个麻烦的问题,用去半天的时间很正常。学会用windbg之后,死锁一般都可以在十几分钟搞定。 http://spaces.msn.com/gerogepei/

解决方案 »

  1.   

    Of course, I'm a good man. HAHA.In fact, I just want to attract people to UP this post. HEIHEI.
      

  2.   

    好文,不给分也顶顶顶
    下面我想讲个故事:我上学的时候做过一个程序,也是在多线程中用了ENABLEWINDOW,当时也是出现了问题2,但我当时不知道怎么回事,抓狂后就改用其他办法解决了,但是,但是一直不知道为什么。知道我找工作面试时,当时面试的对多线程这块特感兴趣,我就谈了一些这方面的内容,当然上述那个问题也包括,结果面试的问我你知道为什么会发生那样的问题吗,我又抓狂一次
    其实我想说的是,我们是生活在微软外面的人,有时候用MFC,本来觉得很简单的一个函数会引起很多问题,我想问楼主和其他各位高手,到底从哪里去获得很多象问题1,2这样的内部细节问题,我需要哪些资料???
      

  3.   

    Inside windows 2000 这本书不错另外,windbg在配备windows的symbol之后,也可以看出一些windows的执行细节。