執行緒同步機制的區別與比較及程序通訊方法

2021-07-27 12:57:02 字數 3260 閱讀 6086

有關多執行緒的一些技術問題:

1、  何時使用多執行緒?

2、  執行緒如何同步?

3、  執行緒之間如何通訊?

4、  程序之間如何通訊?

先來回答第乙個問題,執行緒實際主要應用於四個主要領域,當然各個領域之間不是絕對孤立的,他們有可能是重疊的,但是每個程式應該都可以歸於某個領域:

1、  offloading time-consuming task。由輔助線程來執行耗時計算,而使gui有更好的反應。我想這應該是我們考慮使用執行緒最多的一種情況吧。

2、  scalability。伺服器軟體最常考慮的問題,在程式中產生多個執行緒,每個執行緒做乙份小的工作,使每個cpu都忙碌,使cpu(一般是多個)有最佳的使用率,達到負載的均衡,這比較複雜,我想以後再討論這個問題。

3、  fair-share resource allocation。當你向乙個負荷沉重的伺服器發出請求,多少時間才能獲得服務。乙個伺服器不能同時為太多的請求服務,必須有乙個請求的最大個數,而且有時候對某些請求要優先處理,這是執行緒優先順序幹的活了。

4、  simulations。執行緒用於**測試。

我把主要的目光放在第乙個領域,因為它正是我想要的。第二和第三個領域比較有意思,但是目前不在我的研究時間表中。

執行緒的同步機制:

1、  event

用事件(event)來同步執行緒是最具彈性的了。乙個事件有兩種狀態:激發狀態和未激發狀態。也稱有訊號狀態和無訊號狀態。事件又分兩種型別:手動重置事件和自動重置事件。手動重置事件被設定為激發狀態後,會喚醒所有等待的執行緒,而且一直保持為激發狀態,直到程式重新把它設定為未激發狀態。自動重置事件被設定為激發狀態後,會喚醒「乙個」等待中的執行緒,然後自動恢復為未激發狀態。所以用自動重置事件來同步兩個執行緒比較理想。mfc中對應的類為cevent.。cevent的建構函式預設建立乙個自動重置的事件,而且處於未激發狀態。共有三個函式來改變事件的狀態:setevent,resetevent和pulseevent。用事件來同步執行緒是一種比較理想的做法,但在實際的使用過程中要注意的是,對自動重置事件呼叫setevent和pulseevent有可能會引起死鎖,必須小心。

2、  critical section

使用臨界區域的第乙個忠告就是不要長時間鎖住乙份資源。這裡的長時間是相對的,視不同程式而定。對一些控制軟體來說,可能是數毫秒,但是對另外一些程式來說,可以長達數分鐘。但進入臨界區後必須盡快地離開,釋放資源。如果不釋放的話,會如何?答案是不會怎樣。如果是主線程(gui執行緒)要進入乙個沒有被釋放的臨界區,呵呵,程式就會掛了!臨界區域的乙個缺點就是:critical section不是乙個核心物件,無法獲知進入臨界區的執行緒是生是死,如果進入臨界區的執行緒掛了,沒有釋放臨界資源,系統無法獲知,而且沒有辦法釋放該臨界資源。這個缺點在互斥器(mutex)中得到了彌補。critical section在mfc中的相應實現類是ccriticalsection。ccriticalsection::lock()進入臨界區,ccriticalsection::unlock()離開臨界區。

3、  mutex

互斥器的功能和臨界區域很相似。區別是:mutex所花費的時間比critical section多的多,但是mutex是核心物件(event、semaphore也是),可以跨程序使用,而且等待乙個被鎖住的mutex可以設定timeout,不會像critical section那樣無法得知臨界區域的情況,而一直死等。mfc中的對應類為cmutex。win32函式有:建立互斥體createmutex() ,開啟互斥體openmutex(),釋放互斥體releasemutex()。mutex的擁有權並非屬於那個產生它的執行緒,而是最後那個對此mutex進行等待操作(waitforsingleobject等等)並且尚未進行releasemutex()操作的執行緒。執行緒擁有mutex就好像進入critical section一樣,一次只能有乙個執行緒擁有該mutex。如果乙個擁有mutex的執行緒在返回之前沒有呼叫releasemutex(),那麼這個mutex就被捨棄了,但是當其他執行緒等待(waitforsingleobject等)這個mutex時,仍能返回,並得到乙個wait_abandoned_0返回值。能夠知道乙個mutex被捨棄是mutex特有的。

4、  semaphore

訊號量是最具歷史的同步機制。訊號量是解決producer/consumer問題的關鍵要素。對應的mfc類是csemaphore。win32函式createsemaphore()用來產生訊號量。releasesemaphore()用來解除鎖定。semaphore的現值代表的意義是目前可用的資源數,如果semaphore的現值為1,表示還有乙個鎖定動作可以成功。如果現值為5,就表示還有五個鎖定動作可以成功。當呼叫wait…等函式要求鎖定,如果semaphore現值不為0,wait…馬上返回,資源數減1。當呼叫releasesemaphore()資源數加1,當時不會超過初始設定的資源總數。

執行緒之間的通訊:

執行緒常常要將資料傳遞給另外乙個執行緒。worker執行緒可能需要告訴別人說它的工作完成了,gui執行緒則可能需要交給worker執行緒一件新的工作。

通過postthreadmessage(),可以將訊息傳遞給目標執行緒,當然目標執行緒必須有訊息佇列。以訊息當作通訊方式,比起標準技術如使用全域性變數等,有很大的好處。如果物件是同一程序中的執行緒,可以傳送自定義訊息,傳遞資料給目標執行緒,如果是執行緒在不同的程序中,就涉及程序之間的通訊了。下面將會講到。

程序之間的通訊:

當執行緒分屬於不同程序,也就是分駐在不同的位址空間時,它們之間的通訊需要跨越位址空間的邊界,便得採取一些與同一程序中不同執行緒間通訊不同的方法。

2、  wm_copydata效率上面不是太高,如果要求高效率,可以考慮使用共享記憶體(shared memory)。使用共享記憶體要做的是:設定一塊記憶體共享區域;使用共享記憶體;同步處理共享記憶體。

第二步:使用共享記憶體。共享記憶體指標的使用是一件比較麻煩的事,我們需要借助_based屬性,允許指標被定義為從某一點開始起算的32位偏移值。

第四步:同步處理。可以借助mutex來進行同步處理。

3、  ipc

1)anonymous pipes。anonymous pipes只被使用於點對點通訊。當乙個程序產生另乙個程序時,這是最有用的一種通訊方式。

2)named pipes。named pipes可以是單向,也可以是雙向,並且可以跨越網路,步侷限於單機。

3)mailslots。mailslots為廣播式通訊。server程序可以產生mailslots,任何client程序可以寫資料進去,但是只有server程序可以取資料。

4)ole automation。ole automation和udp都是更高階的機制,允許通訊發生於不同程序間,甚至不同機器間。

5)dde。dde動態資料交換,使用於16位windows,目前這一方式應盡量避免使用。 

執行緒同步機制的區別與比較及程序通訊方法

有關多執行緒的一些技術問題 1 何時使用多執行緒?2 執行緒如何同步?3 執行緒之間如何通訊?4 程序之間如何通訊?先來回答第乙個問題,執行緒實際主要應用於四個主要領域,當然各個領域之間不是絕對孤立的,他們有可能是重疊的,但是每個程式應該都可以歸於某個領域 1 offloading time con...

程序 執行緒同步機制

程序執行緒之間的通訊共享資料在現實的應用中可以說是不可避免的,那麼如何保證他們之間在使用同乙個資料的時候能夠有序,不出問題,這個就是同步機制要解決的問題,老師經常說程式設計到最後有很多哲學的問題,仔細想來也確實可以這麼說,哈哈,其實哲學就是事物的道理嗎,我們都多多少少是跟哲學沾邊的。同步的機制主要有...

程序 執行緒間同步機制。

一 程序 執行緒間同步機制。臨界區 互斥區 事件 訊號量四種方式 臨界區 critical section 互斥量 mutex 訊號量 semaphore 事件 event 的區別 1 臨界區 通過對多執行緒的序列化來訪問公共資源或一段 速度快,適合控制資料訪問。在任意時刻只允許乙個執行緒對共享資源...