直接使用的方法如下:
- //////////////////////////////////////////////////////////////////////////
- // CopyRight(c) 2009, YOYO, All Rights Reserved.
- // Author: LIN YiQian
- // Created: 2009/09/16
- // Describe: 使用临界区实现同步 演示
- //////////////////////////////////////////////////////////////////////////
- #include <Windows.h>
- #include <iostream>
- using namespace std;
- DWORD WINAPI SellTickets(LPVOID lpParameter);
- int g_nTickets = 100;
- CRITICAL_SECTION g_cs;
- void main(void)
- {
- InitializeCriticalSection(&g_cs);
- HANDLE hThread1 = CreateThread(NULL, 0, SellTickets, new int(1), 0, NULL);
- HANDLE hThread2 = CreateThread(NULL, 0, SellTickets, new int(2), 0, NULL);
- HANDLE hThread3 = CreateThread(NULL, 0, SellTickets, new int(3), 0, NULL);
- CloseHandle(hThread1);
- CloseHandle(hThread2);
- CloseHandle(hThread3);
- Sleep(1000);
- DeleteCriticalSection(&g_cs);
- system("pause");
- return;
- }
- DWORD WINAPI SellTickets(LPVOID lpParameter)
- {
- while (true)
- {
- EnterCriticalSection(&g_cs);
- if (g_nTickets > 0)
- {
- printf("Thread %d sells ticket: No.%d/n", *((int*)lpParameter), g_nTickets--);
- }
- else
- {
- break;
- }
- LeaveCriticalSection(&g_cs);
- }
- return NULL;
- }
但是每次都EnterCriticalSection、LeaveCriticalSection有点小麻烦,因此可以封装成一个类方便操作:
【声明】
- //////////////////////////////////////////////////////////////////////////
- // CopyRight(c) 2009, YOYO, All Rights Reserved.
- // Author: LIN YiQian
- // Created: 2009/09/16
- // Describe: 封装的临界区类
- //////////////////////////////////////////////////////////////////////////
- #ifndef _MULTITHREAD_CRITICALLOCK_H_
- #define _MULTITHREAD_CRITICALLOCK_H_
- #if _MSC_VER > 1000
- #pragma once
- #endif
- #include <Windows.h>
- class CCriticallLock
- {
- public:
- CCriticallLock(void);
- ~CCriticallLock(void);
- public:
- void Lock(void);
- void Unlock(void);
- private:
- CRITICAL_SECTION m_objCriticalSection;
- };
- #endif // end of define _MULTITHREAD_CRITICALLOCK_H_
【定义】
- //////////////////////////////////////////////////////////////////////////
- // CopyRight(c) 2009, YOYO, All Rights Reserved.
- // Author: LIN YiQian
- // Created: 2009/09/16
- // Describe: 封装的临界区类
- //////////////////////////////////////////////////////////////////////////
- #include "CriticallLock.h"
- CCriticallLock::CCriticallLock(void)
- {
- InitializeCriticalSection(&m_objCriticalSection);
- }
- CCriticallLock::~CCriticallLock(void)
- {
- DeleteCriticalSection(&m_objCriticalSection);
- }
- void CCriticallLock::Lock()
- {
- EnterCriticalSection(&m_objCriticalSection);
- }
- void CCriticallLock::Unlock()
- {
- LeaveCriticalSection(&m_objCriticalSection);
- }
【使用】
- //////////////////////////////////////////////////////////////////////////
- // CopyRight(c) 2009, YOYO, All Rights Reserved.
- // Author: LIN YiQian
- // Created: 2009/09/16
- // Describe: 封装的临界区类 使用
- //////////////////////////////////////////////////////////////////////////
- #include "CriticallLock.h"
- #include <Windows.h>
- #include <iostream>
- using namespace std;
- DWORD WINAPI SellTickets(LPVOID lpParameter);
- int g_nTickets = 100;
- CCriticallLock g_objCriticallLock;
- void main(void)
- {
- HANDLE hThread1 = CreateThread(NULL, 0, SellTickets, new int(1), 0, NULL);
- HANDLE hThread2 = CreateThread(NULL, 0, SellTickets, new int(2), 0, NULL);
- HANDLE hThread3 = CreateThread(NULL, 0, SellTickets, new int(3), 0, NULL);
- CloseHandle(hThread1);
- CloseHandle(hThread2);
- CloseHandle(hThread3);
- Sleep(1000);
- system("pause");
- return;
- }
- DWORD WINAPI SellTickets(LPVOID lpParameter)
- {
- while (true)
- {
- g_objCriticallLock.Lock();
- if (g_nTickets > 0)
- {
- printf("Thread %d sells ticket: No.%d/n", *((int*)lpParameter), g_nTickets--);
- }
- else
- {
- break;
- }
- g_objCriticallLock.Unlock();
- }
- return NULL;
- }
但是,使用临界区不当时会发生死锁,样例如下:
- //////////////////////////////////////////////////////////////////////////
- // CopyRight(c) 2009, YOYO, All Rights Reserved.
- // Author: LIN YiQian
- // Created: 2009/09/16
- // Describe: 使用临界区造成死锁样例
- //////////////////////////////////////////////////////////////////////////
- #include <Windows.h>
- #include <iostream>
- using namespace std;
- DWORD WINAPI ThreadFun1(LPVOID lpParameter);
- DWORD WINAPI ThreadFun2(LPVOID lpParameter);
- CRITICAL_SECTION g_csA;
- CRITICAL_SECTION g_csB;
- void main(void)
- {
- InitializeCriticalSection(&g_csA);
- InitializeCriticalSection(&g_csB);
- HANDLE hThread1 = CreateThread(NULL, 0, ThreadFun1, NULL, 0, NULL);
- HANDLE hThread2 = CreateThread(NULL, 0, ThreadFun2, NULL, 0, NULL);
- CloseHandle(hThread1);
- CloseHandle(hThread2);
- Sleep(3000);
- DeleteCriticalSection(&g_csA);
- DeleteCriticalSection(&g_csB);
- system("pause");
- return;
- }
- DWORD WINAPI ThreadFun1(LPVOID lpParameter)
- {
- while (true)
- {
- EnterCriticalSection(&g_csA);
- EnterCriticalSection(&g_csB);
- printf("Thread1 is running../n");
- LeaveCriticalSection(&g_csB);
- LeaveCriticalSection(&g_csA);
- }
- return NULL;
- }
- DWORD WINAPI ThreadFun2(LPVOID lpParameter)
- {
- while (true)
- {
- EnterCriticalSection(&g_csB);
- EnterCriticalSection(&g_csA);
- printf("Thread2 is running../n");
- LeaveCriticalSection(&g_csA);
- LeaveCriticalSection(&g_csB);
- }
- return NULL;
- }