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】

  • 相关阅读:
    django 模型层
    django 模板层
    django的视图层
    django-2的路由层(URLconf)
    django简介
    [Codeforces] 650A
    [codevs2916] 校门外的树2
    [Codevs 1690] 开关灯
    codevs3027线段覆盖2(DP)题解
    BC#65T4 ZYB's Tree
  • 原文地址:https://www.cnblogs.com/qrlozte/p/6658073.html
Copyright © 2011-2022 走看看