當多個執行緒訪問同乙個全域性變數,或者同乙個資源(比如印表機)的時候,需要進行執行緒間的互斥操作來保證訪問的安全性。
臨界區、互斥體、事件和訊號量都可以實現執行緒互斥.但如果僅僅需要實現互斥功能,推薦前兩種:
兩者的區別:
1、臨界區只能用於程序內的執行緒互斥,效能較好.
2、互斥體屬於核心物件,可以用於程序間的執行緒互斥,效能較差.
3、執行緒在沒有正常退出互斥區而意外終結時,互斥體可以復位,但臨界區不行.
當有多個執行緒同時執行時,可能需要執行緒按照一定的順序執行,比如:執行緒a負責將要處理的資料讀取到記憶體中,而執行緒b負責分析這些資料,此時,應該是執行緒a執行完畢再執行執行緒b才有意義,這個時候就需要進行執行緒的同步控制。
可以用於執行緒同步控制的物件:事件和訊號量
兩者的區別:
1、都是核心物件,使用完畢後應該關閉控制代碼.
2、訊號量可以用於相當複雜的執行緒同步控制.
臨界區的使用:
1、建立critical_section:
critical_section cs;
2、在使用前進行初始化
initializecriticalsection(&cs);
3、在函式中使用:
dword winapi 執行緒a(pvoid pvparam)
dword winapi 執行緒b(pvoid pvparam)
4、刪除critical_section
void deletecriticalsection(pcritical_section pcs);
當執行緒不再試圖訪問共享資源時
互斥體的使用:
handle createmutexw(
lpsecurity_attributes lpmutexattributes,
bool binitialowner, // false:建立後,能直接使用(有訊號)
// true: 建立後,不能直接使用(沒訊號),表示當前互斥體屬於當前的程序
lpcwstr lpname // 給核心互斥體命名
獲取互斥體令牌的方式:
有訊號線程的擁有者 (即使引數為 true,a程序仍能獲取互斥體,但 b程序無法獲取)
// 互斥體.cpp (a程序)
int main() {
// 建立乙個互斥體
handle hmutex = createmutex(null, false, l"xyz");
// 獲取互斥體
waitforsingleobject(hmutex, infinite);
for (int i = 0; i < 10; i++) {
sleep(1000);
printf(「a程序的x執行緒 %d\n」, i);
// 釋放互斥體
releasemutex(hmutex);
return 0;
// test.cpp (b程序)
int main() {
handle hmutex = createmutex(null, false, l"xyz");
// 這個互斥體建立失敗,因為 a程序已經建立了乙個同名互斥體
// 但仍會返回同名互斥體的控制代碼
waitforsingleobject(hmutex, infinite);
for (int i = 0; i < 10; i++) {
sleep(1000);
printf(「b程序的y執行緒 %d\n」, i);
releasemutex(hmutex);
return 0;
事件的使用:
1、事件物件的建立
handle createevent(
lpsecurity_attributes lpeventattributes, // 安全屬性 null時為系統預設
bool bmanualreset, // true 通過呼叫resetevent將事件物件標記為未通知
bool binitialstate, // true 已通知狀態 false未通知狀態
lpctstr lpname // 物件名稱 以null結尾的字串
);2、事件物件的控制
bool setevent(handle hevent); //將物件設定為已通知
3、關閉時間物件控制代碼
closehandle(); //關閉控制代碼
訊號量的使用:
建立訊號量
handle createsemaphore(
lpsecurity_attributes lpsemaphoreattributes,
long linitialcount,
long lmaximumcount,
lpctstr lpname
函式說明:
第乙個引數表示安全控制,一般直接傳入null。
第二個引數表示初始資源數量。0時不傳送訊號
第三個引數表示最大併發數量。linitialcount<=lmaximumcount
第四個引數表示訊號量的名稱,傳入null表示匿名信號量。
開啟訊號量
handle opensemaphore(
dword dwdesiredaccess,
bool binherithandle,
lpctstr lpname
函式說明:
第乙個引數表示訪問許可權,對一般傳入semaphore_all_access。詳細解釋可以檢視msdn文件。
第二個引數表示訊號量控制代碼繼承性,一般傳入false即可。
第三個引數表示名稱,不同程序中的各執行緒可以通過名稱來確保它們訪問同乙個訊號量。
遞增訊號量的當前資源計數
bool releasesemaphore(
handle hsemaphore,
long lreleasecount,
lplong lppreviouscount
函式說明:
第乙個引數是訊號量的控制代碼。
第二個引數表示增加個數,必須大於0且不超過最大資源數量。
第三個引數返回當前資源數量的原始值,設為null表示不需要傳出。
注:沒有乙個函式可以用來查詢信標的當前資源數量的值
訊號量的清理與銷毀
closehandle()
執行緒同步與互斥
與多程序互動一樣,各個不同的執行緒之間也會存在資源的共享問題。為了解決多執行緒之間對資源訪問的同步和互斥問題,我們需要了解執行緒同步機制。第一種機制 互斥鎖 互斥鎖是一種簡單的加鎖方法,可以使單個執行緒進行對資源訪問的原子操作。互斥鎖的基本操作就是加鎖和解鎖。互斥鎖主要包含以下函式 1 初始化函式 ...
執行緒同步與互斥
1.執行緒互斥 執行緒互斥是指某一資源同時只允許乙個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。同步就是協同步調,按預定的先後次序進行執行。如 你說完,我再說。同 字從字面上容易理解為一起動作 其實不是,同 字應是指協同 協助 互相配合。如程序 執行...
執行緒的同步與互斥
進行多執行緒程式設計,因為無法知道哪個執行緒會在哪個時候對共享資源進行操作,因此讓如何保護共享資源變得複雜,通過下面這些技術的使用,可以解決 執行緒之間對資源的競爭 1.互斥量mutex 2.訊號燈semaphore 3.條件變數 conditions mutex 互斥鎖線程控制 1 互斥鎖是用一種...