執行緒間通訊

2021-06-13 03:47:36 字數 3080 閱讀 5420

執行緒間的通訊:

在乙個多執行緒的應用程式中,所有執行緒共享程序資源,協同工作。所以,執行緒之間的通訊是編寫多執行緒

應用的必不可少的環節。

執行緒之間的通訊包括互斥、同步等,它是多

執行緒設計中最難控制的部分,也是關鍵部分。

1、執行緒間的互斥

(1) 臨界區

在乙個多執行緒

的應用程式中,可能存在這樣的危險:乙個執行緒以某種其他執行緒不可預料的方式修改資源。

例如兩個執行緒都對同乙個檔案進行讀寫,兩個執行緒都在進行繪圖,乙個執行緒正在使用一段記憶體而另乙個執行緒卻正在修改這段記憶體的值等,都可能出現不可預料的結果。

可以把不允許多個執行緒交叉執行的一段程式稱為臨界

區。它是由於多個執行緒共享公用資料或公用變數而引起的。

臨界區也被稱為:訪問公用資料的那段程式

。(2) 互斥

為使多個執行緒在進入自己的臨界區時不出現問題,需要實現執行緒的互斥執行。它應

滿足:·各執行緒平等,都可隨時進入臨界區

。·乙個不在臨界區執行的執行緒

,不可以阻止其他執行緒進入臨界區

。·當乙個執行緒正在臨界區內執行時,必須阻止其他執行緒進入臨界

區。·多個執行緒申請進入臨界區時,只能允許乙個執行緒進入。

·乙個申請進入臨界區的執行緒,應該能在有限時間內進入,不會發生死鎖。

(3) 臨界區類

mfc定義了臨界區封裝類ccriticalsectio

n,可以比較方便的實現執行緒間的互斥。

首先定義乙個ccriticalsection

類物件,該物件通常應被定義為全域性變數,以便跨執行緒使用。

當執行緒要進入臨界區時,呼叫其成員函式lock()。若臨界區空閒,該函式將鎖定臨界區;若臨界區已經被鎖定,該函式將被阻塞(不耗費機時),直至臨界區解

鎖。當執行緒要退出臨界區時,呼叫其成員函式unlock()解鎖,以便其他執行緒可以進入臨界區。

2、執行緒間的同步

(1) 執行緒間的直接制約

有時乙個執行緒的執行條件是另乙個執行緒的執行結果,所以只有等待另乙個執行緒完成某項操作後,該執行緒才可繼續執行。例如計算執行緒和列印執行緒。

這種由於執行緒間的功能邏輯關係引起的,稱為執行緒間的直接制約。而由於共享資源引起的執行緒執行速度的制約,稱為間接

制約。存在直接制約關係的乙個執行緒可以在另乙個執行緒的執行條件滿足後,給對方傳送相應訊息或訊號。這樣,被制約的執行緒可以在條件不滿足時處於阻塞狀態,條件滿足後,被對方喚醒繼續工作。

這就是執行緒間的同步方式。

(2) 等待函式

被制約的線

程等待條件的滿足時,可以使用win32 api的訊號等待函式。

若等到訊號或在時限內未等到訊號

,等待函式都將返回,否則執行緒阻塞。

函式waitforsingleobject()等待乙個物件的訊號狀態。

dword waitforsingleobject(handle hhandle, dword dwmilliseconds);

其中:hhandle可以是事件物件、互斥物件或訊號量等。

dwmilliseconds為等待時限,可以為0,也可以為infinite表示無限期等待。

函式返回值為wait_object_0表明有訊號或wait_timeout表明超時。

函式waitformultipleobjects()可以同時等待多各物件的訊號狀態。

dword waitformultipleobjects(dword ncount, const handle *lphandles, bool fwaitall, dword dwmilliseconds);

其中:ncount為等待的物件的個數。

lphandles為存放等待的物件的陣列。

fwaitall等於true指明所有物件均有訊號時返回。

fwaitall等於false指明其中之一有訊號時返回。

(3) 事件物件

mfc定義了cevent類封裝了系統的事件物件。它可以延遲乙個執行緒的執行以等待另乙個執行緒。

事件物件可以是有訊號狀態或無訊號狀態,可以被等待函式呼叫。函式setevent()和resetevent()用於將事件置為有訊號狀態或無訊號狀態。

事件物件有兩種復位方式:

·手工復位:當有訊號時,無論釋放了多少等待的執行緒,只有在resetevent()後才置為無訊號。

·自動復位:當有訊號時,只要釋放了乙個等待的執行緒,就自動轉為無訊號。其他等待執行緒或同一執行緒的下一次等待不被釋放。

事件物件的初始化:

cevent(bool binitiallyown = false, bool bmanualreset = false);

其中:binitiallyown =false初始化為無訊號狀態,=true初始化為有訊號狀態。

bmanualreset =false為自動復位,=true為手工復位。

(4) 互斥物件

mfc定義了cmutex類封裝了系統的互斥物件。它可以保護共享資源防止其為多個執行緒同時訪問。

互斥物件與臨界區非常相似,只是互斥物件可在程序間使用,而臨界區只能用於同一程序的執行緒,但其速度相對較快

互斥物件在未被任何執行緒擁用時為有訊號狀態,當被任乙個執行緒擁有時為無訊號。

當關於互斥物件的等待函式返回成功時,互斥物件變為無訊號。當程序結束後,則需呼叫unlock()函式以使互斥物件變為有訊號。

互斥物件的初始化:

cmutex(bool binitiallyown = false);

其中:binitiallyown 為互斥物件的初始狀態。

(5) 訊號量物件

mfc定義了cse

maphore類封裝了系統的訊號量物件。它是維護乙個從0到指定的最大值的計數的同步物件。

當訊號量物件建立時,擁有乙個初始計數,當執行緒使用和釋放訊號量時,計數增減。只要計數大於0,訊號量都處於有訊號狀態,若計數為0,訊號量處於無訊號狀態。

訊號量主要用於限制執行緒的最大數目。當關於訊號量的等待函式返回成功時,訊號量的計數自動減一。當程序結束後,則需呼叫unlock()函式以使計數加一。

訊號量物件的初始化:

csemaphore(long linitialcount = 1, long lmaxcount = 1);

其中:linitialcount 為訊號量的初始計數。

lmaxcount 為訊號量的最大計數。

執行緒間通訊

執行緒間通訊 多個執行緒在操作統一資源,但各個執行緒操作的動作不同。資源 class res class input implements runnable public void run else x x 1 2 class output implements runnable public vo...

執行緒間通訊

執行緒間通訊 其實就是多個執行緒在操作同乙個資源 但是操作的動作不同。等待喚醒機制 wait notify 0 notifyall 都使用在同步中,因為要對持有監視器 鎖 的執行緒操作。所以要使用在同步中,因為只有同步才具有鎖 為什麼這些操作執行緒的方法要定義object類中呢?因為這些方法在操作同...

執行緒間通訊

執行緒間通訊 多個執行緒在處理同一資源,但是任務卻不同。下面編寫乙個輸入輸出例項 資源 class resource 輸入 class input implements runnable public void run else x x 1 2 輸出 class output implements ...