執行緒的互斥與同步

2021-10-08 07:16:42 字數 3208 閱讀 6466

當多個執行緒訪問同乙個全域性變數,或者同乙個資源(比如印表機)的時候,需要進行執行緒間的互斥操作來保證訪問的安全性。

臨界區、互斥體、事件和訊號量都可以實現執行緒互斥.但如果僅僅需要實現互斥功能,推薦前兩種:

​兩者的區別:

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 互斥鎖是用一種...