C++临界区自动锁

偷懒copy了一个网上现成的自动锁,嵌入项目后调试中屡屡出问题,原类如下:

class CLock
{
public:  
    CLock()  
    {  
        InitializeCriticalSection(&m_cs);  
    }  
  
    ~CLock()
    {  
        DeleteCriticalSection(&m_cs);  
    }  
  
    void Lock()  
    {  
        EnterCriticalSection(&m_cs);
    }  
  
    void Unlock()
    {  
        LeaveCriticalSection(&m_cs);  
    }  
private:  
    CRITICAL_SECTION    m_cs;  
};

class AutoLock
{
public:
    AutoLock()  
    {
        m_lock.Lock();
    }  
    ~AutoLock()
    {
        m_lock.Unlock();
    }
private:
    CLock   m_lock;
private:
    AutoLock(const AutoLock& lock);
    AutoLock& operator=(const AutoLock& lock);
};

调用时使用 

AutoLock auto_lock; 

测试代码:

#define THREAD_NUM 64     //最大只能64线程
int   g_nResource;

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    {
        AutoLock auto_lock;
        printf("Thread id %d Resource Count %d\n",
               GetCurrentThreadId(),
               g_nResource);
        g_nResource++;
    }
    Sleep(1);
    return 0;
}

int main(int argc, char *argv[])
{
    HANDLE hThreads[THREAD_NUM] = {0};
    for(int i = 0; i < THREAD_NUM; i++)
        hThreads[i] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
    WaitForMultipleObjects(THREAD_NUM, hThreads, TRUE, INFINITE);
    getchar();
    return 0;
}

分析发现是 AutoLock auto_lock; 每次创建的CLock是私有变量,没法解决共享问题。

因此要解决,其一,将CLock调整为全局变量,但带来安全问题。其二,定义为局部静态变量。

class CLock
{
public:  
    CLock()  
    {  
        InitializeCriticalSection(&m_cs);  
    }  
  
    ~CLock()
    {  
        DeleteCriticalSection(&m_cs);  
    }  
  
    void Lock()  
    {  
        EnterCriticalSection(&m_cs);
    }  
  
    void Unlock()
    {  
        LeaveCriticalSection(&m_cs);  
    }  
private:  
    CRITICAL_SECTION    m_cs;  
};

class AutoLock
{
public:
    AutoLock()  
    {
        m_lock.Lock();
    }  
    ~AutoLock()
    {
        m_lock.Unlock();
    }
private:
    static CLock   m_lock;//声明,全局中初始化
private:
    AutoLock(const AutoLock& lock);
    AutoLock& operator=(const AutoLock& lock);
};
CLock  AutoLock::m_lock;//初始化

再次测试,OK!


猜你喜欢

转载自blog.csdn.net/gongzhu110/article/details/80027728