zoukankan      html  css  js  c++  java
  • 【转】suspend造成死锁

    备注:我最近的项目就遇到了这个问题。只用了一个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(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族函数来暂停线程。

    【END】

  • 相关阅读:
    解决 EDAS:Upload failed: The right margin is 0.535 in on page 1 问题
    解决 ImportError: No module named _internal
    静态页面如何实现 include 引入公用代码
    一个用 js 实现点阵图的编辑器演示
    从 art-template 模版维护到动态加载的思考
    Atom 备份神器 —— Sync Settings
    clicaptcha中文点击验证码开发经验总结
    通过 imagick 让 PHP 生成 PSD 文件缩略图
    让视频压制更简单
    Medoo个人修改版
  • 原文地址:https://www.cnblogs.com/qrlozte/p/6658073.html
Copyright © 2011-2022 走看看