EnterCriticalSection似乎没有阻止

时间:2014-10-18 04:51:44

标签: c++ windows

我有以下代码来创建线程来完成一些工作(为清楚起见省略了部分)。

 CRITICAL_SECTION gCS;

 class Locker
 {
     public:
    Locker(CRITICAL_SECTION& cs): m_cs(cs)
     {
         EnterCriticalSection(&m_cs);
     }
     ~Locker()
     {
         LeaveCriticalSection(&m_cs);
     }
     private:
        CRITICAL_SECTION  m_cs;
 };

 ...

 HRESULT MyClass::FinalConstruct()
 {
   InitializeCriticalSection(&gCS);
 }

 ...

 DWORD WINAPI MyClass::CreateThread()
 {

        hWriteReceiptThread = CreateThread( 
                NULL,                   // default security attributes
                0,                      // use default stack size  
                MyClass::RunThread,       // thread function name
                NULL,          // argument to thread function 
                0,                      // use default creation flags 
                &dwThreadId);   // returns the thread identifier 
        return 0;
 }


 DWORD WINAPI MyClass::RunThread(LPVOID args)
 {
        {
                LogInfo("getting lock for critical Section");
                Locker lock(gCS);
                EnterCriticalSection(&gCS);
                LogInfo("entered Critical Section");

         //... do lots of stuff

                LogInfo("leaving critical section");
                LeaveCriticalSection(&gCS);
                LogInfo("left critical section");
        }
 }

当它运行时,会出现以下打印语句(每个print语句打印在语句之前从GetCurrentThreadId()返回的数字。看起来好像关键部分没有效果。例如,线程7608获取锁定然后以下两个线程在完成之前也会获得锁定。任何人都可以深入了解这可能发生的情况吗?

 16004 Critical section initialised
 7608 getting lock for critical Section
 7608 Entered Critical Section
 11412 getting lock for critical Section
 11412 Entered Critical Section
 12860 getting lock for critical Section
 6552 getting lock for critical Section
 6552 Entered Critical Section
 5524 getting lock for critical Section
 5524 Entered Critical Section
 7608 leaving critical section
 7608 left critical section

由于

1 个答案:

答案 0 :(得分:6)

根据the documentation

  

无法移动或复制关键部分对象。

您正在复制关键部分并对副本进行操作。

Locker(CRITICAL_SECTION& cs): m_cs(cs)
                              ^^^^^^^^
...
CRITICAL_SECTION m_cs;

您可能想要复制参考,而不是实际的临界区。

CRITICAL_SECTION& m_cs;
                ^ reference