本篇文章介紹如何使用訊號量解決執行緒的同步互斥。
首先也來看看如何使用訊號量,訊號量semaphore常用有三個函式,使用很方便。下面是這幾個函式的原型和使用說明。
第乙個 createsemaphore函式功能:建立訊號量
函式原型:
handle createsemaphore(
lpsecurity_attributes lpsemaphoreattributes,
long linitialcount,
long lmaximumcount,
lpctstr lpname
);函式說明:
第乙個引數表示安全控制,一般直接傳入null。
第二個引數表示初始資源數量。
第三個引數表示最大併發數量。
第四個引數表示訊號量的名稱,傳入null表示匿名信號量。
第二個 opensemaphore函式功能:開啟訊號量
函式原型:
handle opensemaphore(
dword dwdesiredaccess,
bool binherithandle,
lpctstr lpname
);函式說明:
第乙個引數表示訪問許可權,對一般傳入semaphore_all_access。詳細解釋可以檢視msdn文件。
第二個引數表示訊號量控制代碼繼承性,一般傳入true即可。
第三個引數表示名稱,不同程序中的各執行緒可以通過名稱來確保它們訪問同乙個訊號量。
第三個 releasesemaphore注意:當前資源數量大於0,表示訊號量處於觸發,等於0表示資源已經耗盡故訊號量處於末觸發。在對訊號量呼叫等待函式時,等待函式會檢查訊號量的當前資源計數,如果大於0(即訊號量處於觸發狀態),減1後返回讓呼叫執行緒繼續執行。乙個執行緒可以多次呼叫等待函式來減小訊號量。函式功能:遞增訊號量的當前資源計數
函式原型:
bool releasesemaphore(
handle hsemaphore,
long lreleasecount,
lplong lppreviouscount
);函式說明:
第乙個引數是訊號量的控制代碼。
第二個引數表示增加個數,必須大於0且不超過最大資源數量。
第三個引數可以用來傳出先前的資源計數,設為null表示不需要傳出。
最後乙個 訊號量的清理與銷毀還是之前的那個執行緒同步互斥的問題,**實現:由於訊號量是核心物件,因此使用closehandle()就可以完成清理與銷毀了。
#include #include #include int g_num;執行結果圖:const int thread_num = 10;
//訊號量和關鍵段
handle g_hthreadparam;
critical_section g_csthreadcode;
unsigned int __stdcall fun(void *param)
int main(void)
waitformultipleobjects(thread_num, handle, true, infinite);
deletecriticalsection(&g_csthreadcode);
closehandle(g_hthreadparam);
for (i = 0; i < thread_num; i++)
return 0;
}
可以看出來,訊號量也可以解決執行緒之間的同步問題。
由於訊號量可以計算資源當前剩餘量並根據當前剩餘量與零比較來決定訊號量是處於觸發狀態或是未觸發狀態,因此訊號量的應用範圍相當廣泛。
乙個經典的多執行緒同步問題
本篇文章參考了 程式描述 主線程啟動10個子執行緒並將表示子線程式號的變數位址作為引數傳遞給子執行緒。子執行緒接收引數 sleep 50 全域性變數 sleep 0 輸出引數和全域性變數。要求 1 子執行緒輸出的線程式號不能重複。2 全域性變數的輸出必須遞增。下面畫了個簡單的示意圖 分析下這個問題的...
乙個經典的多執行緒同步問題 問題引入
下面來看乙個經典的多執行緒的同步和互斥的問題,問題的描述 主線程啟動10個子執行緒並將表示子線程式號的變數的位址作為引數傳遞給子執行緒。子執行緒接收引數 sleep 50 全域性變數 sleep 0 輸出引數和全域性變數。要求 1.子執行緒輸出的線程式號不能重複 2.全域性變數的輸出必須是遞增的 下...
乙個經典的多執行緒同步問題01 問題重現
程式描述 主線程啟動10個子執行緒並將表示子線程式號的變數位址作為引數傳遞給子執行緒。子執行緒接收引數 sleep 50 全域性變數 sleep 50 輸出引數和全域性變數。要求 1 子執行緒輸出的線程式號不能重複。2 全域性變數的輸出必須遞增。下面畫了個簡單的示意圖 分析下這個問題的考察點,主要考...