I was lazy and copied a ready-made automatic lock on the Internet. After embedding the project, there were many problems in debugging. The original class is as follows:
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); };
used when calling
AutoLock auto_lock;
Test code:
#define THREAD_NUM 64 //Maximum only 64 threads 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; }
The analysis found that it is AutoLock auto_lock; the CLock created each time is a private variable, which cannot solve the sharing problem.
Therefore, to solve, first, adjust CLock to a global variable, but it brings security problems. Second, it is defined as a local static variable.
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;//Declaration, initialized in the global private: AutoLock(const AutoLock& lock); AutoLock& operator=(const AutoLock& lock); }; CLock AutoLock::m_lock;//Initialization
Test again, OK!