备注:我最近的项目就遇到了这个问题。只用了一个CCriticalSection对象,并且全部都有释放。但还是死活没查出死锁的原因。最后才发现原来是suspend导致的。最终用CEvent替代了suspend和resume才解决。

======================

转自:http://blog.csdn.net/magictong/article/details/4161571

今天loris分享了一个关于使用suspend造成死锁的例子,部分代码如下:

UINT AFX_CDECL ThreadTest(LPVOID pvParam)
{
while (TRUE)
{
HMODULE hHandle = ::LoadLibrary("Common.dll");
if (hHandle)
{
void *pFun = (void *)::GetProcAddress(hHandle, "doSomething");
::FreeLibrary(hHandle);
}
::Sleep();
}
} void CTESTWIN2Dlg::OnOK()
{
CWinThread *pThread = AfxBeginThread(ThreadTest, (LPVOID)this,
, ,
CREATE_SUSPENDED); ::DuplicateHandle(::GetCurrentProcess(), pThread->m_hThread,
::GetCurrentProcess(), &m_hThread,
, FALSE, DUPLICATE_SAME_ACCESS);
pThread->ResumeThread();
m_bIsRun = TRUE;
SetTimer(, , 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族函数来暂停线程。

【END】

【转】suspend造成死锁的更多相关文章

  1. 深入理解Java中的锁(二)

    locks包结构层次 Lock 接口 方法签名 描述 void lock(); 获取锁(不死不休) boolean tryLock(); 获取锁(浅尝辄止) boolean tryLock(long ...

  2. Thread.suspend和println使线程死锁

    Thread.suspend和println使线程死锁 package com.stono.thread2.page39; public class MyThread extends Thread{ ...

  3. jstack简单使用,定位死循环、线程阻塞、死锁等问题

    当我们运行java程序时,发现程序不动,但又不知道是哪里出问题时,可以使用JDK自带的jstack工具去定位: 废话不说,直接上例子吧,在window平台上的: 死循环 写个死循环的程序如下: pac ...

  4. 被废弃的 Thread.stop, Thread.suspend, Thread.resume 和Runtime.runFinalizersOnExit

    最近学习多线程的知识,看到API里说这些方法被废弃了,就查了一下原因 Thread.stop 这个方法会解除被加锁的对象的锁,因而可能造成这些对象处于不一致的状态,而且这个方法造成的ThreadDea ...

  5. java 死锁及解决

    Java线程死锁如何避免这一悲剧  Java线程死锁需要如何解决,这个问题一直在我们不断的使用中需要只有不断的关键.不幸的是,使用上锁会带来其他问题.让我们来看一些常见问题以及相应的解决方法: Jav ...

  6. java 中有几种方法可以实现一个线程? 用什么关键字修 饰同步方法? stop()和 suspend()方法为何不推荐使用?

    java5 以前, 有如下两种:第一种:new Thread(){}.start();这表示调用 Thread 子类对象的 run 方法, new Thread(){}表示一个Thread 的匿名子类 ...

  7. JAVA多线程suspend()、resume()和wait()、notify()的区别

    suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的 resume() 被调用,才能使得线程重新进入可执行状态.典型 ...

  8. Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?

    Thread.stop, Thread.suspend, Thread.resume被标记为废弃的方法.在查看JDK的文档时,提到了下面的参考文章,先是英文版,接着是中文翻译. Why is Thre ...

  9. Java 多线程 死锁 隐性死锁 数据竞争 恶性数据竞争 错误解决深入分析 全方向举例

    在几乎所有编程语言中,由于多线程引发的错误都有着难以再现的特点,程序的死锁或其它多线程错误可能只在某些特殊的情形下才出现,或在不同的VM上运行同一个程序时错误表现不同.因此,在编写多线程程序时,事先认 ...

随机推荐

  1. iOS页面性能优化

    前言 在软件开发领域里经常能听到这样一句话,“过早的优化是万恶之源”,不要过早优化或者过度优化.我认为在编码过程中时刻注意性能影响是有必要的,但凡事都有个度,不能为了性能耽误了开发进度.在时间紧急的情 ...

  2. 【虚拟化系列】VMware vSphere 5.1 网络管理

       网络是VMware vSphere 5.1的基础,所有虚拟机都需要网络来进行通信.如果将所有的虚拟机都看成是物理机,则在网络拓扑上,需要网卡和交换机等不同的网络连接设备和方式.而在虚拟化中,这些 ...

  3. Linux MySQL 4G内存my.cnf配置表(转)

    # The following options will be passed to all MySQL clients[client]character-set-server = utf8  #### ...

  4. centos 为OPENJDK配置JAVA_HOME环境变量,安装MAVEN

    1.安装开发者工具包 yum install java--openjdk-devel -y 2.配置环境变量 vim /etc/profile export JAVA_HOME=/usr/lib/jv ...

  5. window 10 企业版激活

    一. 用管理员权限打开CMD.EXE 接着输入以下命令: slmgr /ipk NPPR9-FWDCX-D2C8J-H872K-2YT43 弹出窗口提示:“成功的安装了产品密钥”. 继续输入以下命令: ...

  6. mysql升级5.5

    对付Linux的问题,其实很多都是权限问题,细心想一下即可. centos6.4默认装的是mysql5.1,使用 yum update 也update不了.google了一下,找到个yum安装的方法: ...

  7. 机器学习---支持向量机(SVM)

    非常久之前就学了SVM,总认为不就是找到中间那条线嘛,但有些地方模棱两可,真正编程的时候又是一团浆糊.參数任意试验,毫无章法.既然又又一次学到了这一章节,那就要把之前没有搞懂的地方都整明确,嗯~ 下面 ...

  8. Fix SCRIPT5009: “RegisterSod” undefined error

    When I set up development environment for apps for SharePoint 2013 and quickly get apps from SharePo ...

  9. Android事件处理的2种方式:监听器与回调

    android组件的事件处理有2种方式: 1.基于监听器的事件处理方式:先定义组件,然后为组件设定监听器. 详见http://blog.csdn.net/jediael_lu/article/deta ...

  10. flowable 中task的相关操作

    1 获取任务列表 1)获取候选人的任务列表 TaskService taskService = processEngine.getTaskService(); List<Task> tas ...