windows平台多執行緒同步之Mutex的應用

2021-09-27 02:46:37 字數 2638 閱讀 6632

作業系統為每乙個執行執行緒安排一定的cpu時間 ——時間片。系統通過一種迴圈的方式為執行緒提供時間片,執行緒在自己的時間內執行,多個執行緒不斷地切換執行,因時間片相當短,因此,給使用者的感覺,就好像執行緒是同時執行的一樣。

單cpu計算機乙個時間只能執行乙個執行緒,如果計算機擁有多個cpu,執行緒就能真正意義上同時執行了。

windows平台下,建立執行緒可以使用windows api 函式createthread來實現,函式宣告是:

winbaseapi

handle

winapi

createthread( lpsecurity_attributes lpthreadattributes, dword dwstacksize, lpthread_start_routine lpstartaddress, lpvoid lpparameter, dword dwcreationflags, lpdword lpthreadid );

引數說明:

lpthreadattributes

執行緒安全性,使用預設安全性,一般預設null

dwstacksize

堆疊大小,0為預設大小

lpstartaddress

執行緒要執行的函式指標,即入口函式

lpparameter

執行緒引數

dwcreationflags

執行緒標記,如為0,則建立後立即執行

lpthreadid

lpdword為返回值型別,一般傳遞位址去接收執行緒的識別符號,一般設為null

因為要使用windows api函式,所以包含:

#include
另外需要標準輸入輸出函式,所以包含:
#include
- 問題引出   以多個售票視窗賣同一張火車票為例,定義乙個全域性的票數tickets,用兩個執行緒來執行賣票,兩個執行緒訪問同乙個變數tickets,先看乙個不正確的寫法:
//問題程式

#include #include dword winapi fun1proc(

lpvoid lpparameter

);dword winapi fun2proc(

lpvoid lpparameter

);int tickets=100;

void main()

dword winapi fun1proc(

lpvoid lpparameter

)dword winapi fun1proc(

lpvoid lpparameter // thread data

)

如果createmutex第二個引數為true,則表示主線程擁有該互斥物件,作業系統將互斥物件的執行緒id設為主執行緒的執行緒id,如果主線程不釋放,則子執行緒會一直等待,此時子執行緒也沒有權利進行釋放,所以使用互斥物件的原則是:誰擁有互斥物件,誰釋放互斥物件。

另外,如果main中

hmutex=createmutex(null,true,null);
並且再次請求互斥物件:

waitforsingleobject(hmutex,infinite);
並呼叫一次釋放互斥物件:

releasemutex(hmutex);
此時子執行緒依然是等待狀態,得不到互斥物件的使用權,原因是:

createmutex(null,true,null)由於第二個引數為true,主線程擁有互斥物件的使用權,互斥物件內部計數器加1,再次呼叫waitforsingleobject請求互斥物件時,內部計數器又加1,計數器是記錄執行緒擁有互斥物件的次數,而只釋放releasemutex了一次,互斥物件依然被占用,所以子執行緒得不到使用權。

因此正確的寫法是:

hmutex=createmutex(null,true,null);

waitforsingleobject(hmutex,infinite);

releasemutex(hmutex);

releasemutex(hmutex);

如果多次請求互斥物件,就應該多次釋放互斥物件。

再看這樣一種情況,執行緒中沒有釋放互斥物件的擁有權:

dword winapi fun1proc(lpvoid lpparameter)

{waitforsingleobject(hmutex,infinite);

cout<<"thread1 is running"《此時執行依然能夠得到輸出:

"thread1 is running "thread2 is running

這是因為:如果執行緒退出時沒有釋放互斥物件,作業系統在銷毀執行緒時會自動將執行緒占用的互斥物件的資訊清除,計數器歸零,這樣其他執行緒(thread2 )就能申請到互斥物件使用權。

if(hmutex)

{if(error_already_exists==getlasterror())

{cout<<"已經有乙個相同應用程式在執行!"<

命名互斥物件的一種應用是:通過命名互斥物件,可以保證當前只有乙個應用程式例項在執行。

Windows中多執行緒的同步

windows程序間同步方式有 1.互斥量 mutex 2.訊號量 semaphore 3.事件 event 4.臨界區 critical section 5.互鎖函式 臨界區和互鎖函式沒有相應的核心物件因而不能跨程序 只能同步同乙個程序的執行緒之間的同步,因為臨界區不能跨越程序的邊界工作。也是因為...

Windows下C 多執行緒同步

程式 是計算機指令的集合,它以檔案的形式儲存在磁碟上。而程序通常被定義為乙個正在執行程式的例項,是乙個程式在其自身位址空間的依次執行活動。程序 執行緒 由執行緒的核心物件和執行緒棧組成 當多執行緒訪問全域性變數時需要多執行緒同步 互斥物件 事件物件 關鍵 段 互斥物件 互斥獨享可以看做是一把房間鑰匙...

windows多執行緒同步 臨界區

推薦參考部落格 秒殺多執行緒第五篇 經典執行緒同步 關鍵段cs 關於臨界區的觀念,一般作業系統書上面都有。適用範圍 它只能同步乙個程序中的執行緒,不能跨程序同步。一般用它來做單個程序內的 快同步,效率比較高 windows中與臨界區有關的結構是 critical section,關於該結構體的內部結...