Windows 平臺下的同步機制 (1)– 臨界區(CriticalSection)
臨界區的使用在線程同步中應該算是比較簡單,說它簡單還是說它同後面講到的其它方法相比更容易理解。舉個簡單的例子:比如說有一個全局變量(公共資源)兩個線程都會對它進行寫操作和讀操作,如果我們在這裏不加以控制,會產生意想不到的結果。假設線程A正在把全局變量加1然後打印在屏幕上,但是這時切換到線程B,線程B又把全局變量加1然後又切換到線程A,這時候線程A打印的結果就不是程序想要的結果,也就產生了錯誤。解決的辦法就是設置一個區域,讓線程A在操縱全局變量的時候進行加鎖,線程B如果想操縱這個全局變量就要等待線程A釋放這個鎖,這個也就是臨界區的概念。
使用方法:
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);
EnterCriticalSection(&cs);
…
LeaveCriticalSection(&cs);
DeleteCriticalSection(&cs);
#include "stdafx.h"
#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;
/****************************************************************
*在使用臨界區的時候要注意,每一個共享資源就有一個CRITICAL_SECTION
*如果要一次訪問多個共享變量,各個線程要保證訪問的順序一致,如果不
*一致,很可能發生死鎖。例如:
* thread one:
* EnterCriticalSection(&c1)
* EnterCriticalSection(&c2)
* …
* Leave…
* Leave…
*
* thread two:
* EnterCriticalSection(&c2);
* EnterCriticalSection(&c1);
* …
* Leave…
* Leave…
*這樣的情況就會發生死鎖,應該讓線程2進入臨界區的順序同線程1相同
****************************************************************/
封裝類:
class Lock;
class CLock
{
public:
CLock() { ::InitializeCriticalSection(&_cs); }
~CLock() { ::DeleteCriticalSection(&_cs); }
private:
friend class Lock;
CRITICAL_SECTION _cs;
CLock(const CLock&);
CLock& operator=(const CLock&);
};
class Lock
{
public:
Lock(CLock& lock) : _lock(lock) { ::EnterCriticalSection(&_lock._cs); }
~Lock() { ::LeaveCriticalSection(&_lock._cs); }
private:
CLock& _lock;
Lock(const Lock&);
Lock& operator=(const Lock&);
};