SuspendThread 造成程序死锁的一个例子
2013-04-29 23:02
357 查看
msdn对SuspendThread 的说明:
This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization. Calling
SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread. To avoid this situation, a
thread within an application that is not a debugger should signal the other thread to suspend itself. The target thread must be designed to watch for this signal and respond appropriately.
虽然大家都知道尽量不要在外面调用 SuspendThread 暂停线程,不要用 TerminateThread 结束线程,但是都停留在感性认识阶段,这里给出了一段示例代码,看看
SuspendThread 造成死锁的情况。
win32下的API基本都是线程安全的,因此API里面有很多线程同步的地方,LoadLibrary里面有一个临界区,线程函数在执行到LoadLibrary里面之后,如果刚好走到LoadLibrary的临界区里面,此时主线程的ontimer触发,将该线程挂起,ontimer继续执行,运行到LoadLibrary后,由于线程中LoadLibrary还没有从临界区出来,此时就造成主线程ontimer里面的LoadLibrary无限等待,主线程挂起。
因此不建议用suspend暂停线程,MSDN也有说明,suspend最好只在debug里面使用。
那怎么使线程挂起呢?可以使用事件等方式,用wait族函数来暂停线程
This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization. Calling
SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread. To avoid this situation, a
thread within an application that is not a debugger should signal the other thread to suspend itself. The target thread must be designed to watch for this signal and respond appropriately.
虽然大家都知道尽量不要在外面调用 SuspendThread 暂停线程,不要用 TerminateThread 结束线程,但是都停留在感性认识阶段,这里给出了一段示例代码,看看
SuspendThread 造成死锁的情况。
UINT AFX_CDECL ThreadTest(LPVOID pvParam) { while (TRUE) { HMODULE hHandle = ::LoadLibrary("Common.dll"); if (hHandle) { void *pFun = (void *)::GetProcAddress(hHandle, "doSomething"); ::FreeLibrary(hHandle); } ::Sleep(10); } } void CTESTWIN2Dlg::OnOK() { CWinThread *pThread = AfxBeginThread(ThreadTest, (LPVOID)this, 0, 0, CREATE_SUSPENDED); ::DuplicateHandle(::GetCurrentProcess(), pThread->m_hThread, ::GetCurrentProcess(), &m_hThread, 0, FALSE, DUPLICATE_SAME_ACCESS); pThread->ResumeThread(); m_bIsRun = TRUE; SetTimer(10, 10, NULL); } void CTESTWIN2Dlg::OnTimer(UINT nIDEvent) { if (m_bIsRun) { ::SuspendThread(m_hThread); m_bIsRun = FALSE; HMODULE hHandle = ::LoadLibrary("TSVul.dat"); if (hHandle) { void *pFun = (void *)::GetProcAddress(hHandle, "MyDoSome"); ::FreeLibrary(hHandle); } } else { ::ResumeThread(m_hThread); m_bIsRun = TRUE; } CDialog::OnTimer(nIDEvent); }
win32下的API基本都是线程安全的,因此API里面有很多线程同步的地方,LoadLibrary里面有一个临界区,线程函数在执行到LoadLibrary里面之后,如果刚好走到LoadLibrary的临界区里面,此时主线程的ontimer触发,将该线程挂起,ontimer继续执行,运行到LoadLibrary后,由于线程中LoadLibrary还没有从临界区出来,此时就造成主线程ontimer里面的LoadLibrary无限等待,主线程挂起。
因此不建议用suspend暂停线程,MSDN也有说明,suspend最好只在debug里面使用。
那怎么使线程挂起呢?可以使用事件等方式,用wait族函数来暂停线程
相关文章推荐
- SuspendThread 造成程序死锁的一个例子
- suspend造成死锁的例子和原因分析 http://blog.csdn.net/magictong/article/details/4161571
- 用程序把word模板中的一个表格复制为多个表格然后填充数据(工资单的例子)
- 微信小程序例子——使用画布组件绘制一个长200px,宽100px的长方形
- 面试题-背过一个死锁的程序
- java线程:一个死锁的小程序
- 一个简单的C#死锁程序
- wait和notify造成死锁的例子
- 一个多线程的死锁和锁争用的例子
- J2ME程序开发环境配置的一个简单例子
- 一个在windows和基于SWT的java程序间拖拽的例子
- 马士兵视频笔试题:用一个程序模拟死锁的问题
- MinGW Developer Studio 中编译dev cpp程序(一个opengl例子)
- 一个例子程序对常量指针的理解
- 一个C++程序例子——指向函数的指针、含有可变形参的函数(备查)
- [数据库测试]强烈推荐一个python ODBC数据源插件,可支持Oracle,Db2,Mysql,Sql-server以及各种数据库版本,附例子和测试程序
- Linux下C程序调用.so(动态链)的一个例子
- 一个小例子说明ios后台daemon程序获取iTunesstore信息
- java怎么编程写一个能导致死锁的程序
- 一个远程注入的例子(让本机的所有程序弹出一个sylar对话框)