C 多執行緒實踐 執行緒同步

2022-02-06 19:08:11 字數 2636 閱讀 8079

下面的**列展了.net對協調或同步執行緒動作的可用的工具:

簡易阻止方法

構成

目的

sleep

阻止給定的時間週期

join

等待另乙個執行緒完成

鎖系統

構成

目的

跨程序?

速度

lock

確保只有乙個執行緒訪問某個資源或某段**。否快

mutex

確保只有乙個執行緒訪問某個資源或某段**。可被用於防止乙個程式的多個例項同時執行。是中等

semaphore

確保不超過指定數目的執行緒訪問某個資源或某段**。是中等

訊號系統

構成

目的

跨程序?

速度

eventwaithandle

允許執行緒等待直到它受到了另乙個執行緒發出訊號。是中等

wait 和 pulse*

允許乙個執行緒等待直到自定義阻止條件得到滿足。否中等

阻止(blocking)

當乙個執行緒通過上面所列的方式處於等待或暫停的狀態,被稱為被阻止。一旦被阻止,執行緒立刻放棄它被分配的cpu時間,將它的threadstate屬性新增為waitsleepjoin狀態,直到停止阻止。停止阻止由以下任一條件觸發:

當執行緒通過(不建議)suspend 方法暫停,不認為是被阻止了。

休眠 和 輪詢

呼叫thread.sleep阻止當前的執行緒指定的時間(或者直到中斷):

static void main()
確切地說,thread.sleep放棄了占用cpu,請求不再被分配時間直到超過某個給定的時間。thread.sleep(0)放棄cpu的時間剛剛夠其它在時間片佇列裡的活動執行緒(如果有的話)被執行。

thread.sleep在阻止方法中是唯一的暫停捕獲windows forms程式的windows訊息的方法,在windows forms程式中是乙個很大的問題,任何對主ui執行緒的阻止都將使程式失去相應。因此一般避免這樣使用,無論資訊獲取是否被「技術地」暫定與否。執行緒類同時也提供了乙個spinwait方法,它使用輪詢cpu而非放棄cpu時間的方式,保持給定的迭代次數進行「無用地繁忙」。50迭代停頓大約一微秒,一般取決於cpu的速度和負載。從技術上講,spinwait並不是乙個阻止的方法:乙個處於spin-waiting的執行緒的threadstate不是waitsleepjoin狀態,並且也不會被其它的執行緒過早的中斷(interrupt)。spinwait很少被使用,它的作用是等待乙個在極短時間(可能小於一微秒)內可準備好的可預期的資源,而不用呼叫sleep方法阻止執行緒而浪費cpu時間。不過,這種技術的優勢只有在多處理器計算機:對單一處理器的電腦,直到輪詢的執行緒結束了它的時間片之前,乙個資源沒有機會改變狀態,這有違它的初衷。並且呼叫spinwait經常會花費較長的時間這本身就浪費了cpu時間。

阻止 vs. 輪詢

執行緒可以等待某個確定的條件來明確輪詢使用乙個輪詢的方式,比如:

while (!proceed);
或者:

while (datetime.now < nextstarttime);
這是非常浪費cpu時間的:對於clr和作業系統而言,執行緒進行了乙個重要的計算,所以分配了相應的資源!在這種狀態

下的輪詢執行緒不算是阻止,不像乙個執行緒等待乙個eventwaithandle(一般使用這樣的訊號任務來構建)。

阻止和輪詢組合使用可以產生一些變換:

while (!proceed) thread.sleep (x); // "輪詢休眠!"
x越大,cpu效率越高,折中方案是增大潛伏時間,任何20ms的花費是微不足道的,除非迴圈中的條件是極其複雜的。

除了稍有延遲,這種輪詢和休眠的方式可以結合的非常好,可能它最大的用處在於程式設計師可以放棄使用複雜的訊號結構來工作了。

使用join等待乙個執行緒完成

可以通過join方法阻止執行緒直到另乙個執行緒結束:

class threaddemo );

t.start();

t.join(); // 等待直到執行緒完成

console.writeline ("thread t's readline complete!");}}

join方法也接收乙個使用毫秒或用timespan類的超時引數,當join超時是返回false,如果執行緒已終止,則返回true 。

join所帶的超時引數非常像sleep方法,實際上下面兩行**幾乎差不多:

thread.sleep (1000);

thread.currentthread.join (1000);
他們的區別明顯在於單執行緒的應用程式域與com互操作性:在阻止時,join保持資訊捕獲,sleep暫停資訊捕獲。

C 多執行緒同步

在開發中經常會遇到執行緒的例子,如果某個後台操作比較費時間,我們就可以啟動乙個執行緒去執行那個費時的操作,同時程式繼續執行。在某些情況下可能會出現多個執行緒的同步協同的問題,下面的例子就展示了在兩個執行緒之間如何協同工作。這個程式的思路是共同做一件事情 從乙個arraylist中刪除元素 如果執行完...

C 多執行緒 執行緒同步事件

1 事件 事件是核心物件,多用於執行緒間通訊,可以跨程序同步 2 事件使用 1 建立事件 handle createevent lpsecurity attribute slpeventattributes,安全控制,一般直接傳入null bool bmanualreset,確定事件是手動還是自動 ...

C 多執行緒執行緒同步問題

程序通常被定義為乙個正在執行的程式的例項,是乙個程式在其自身位址空間中的一次執行活動。程序從來不執行任何東西,它是執行緒的容器。若要程序完成某項操作它必須擁有乙個在它的環境中執行的執行緒,此執行緒負責包含執行包含在程序位址空間中的 現存由執行緒的核心物件和執行緒棧兩部分組成。作業系統用執行緒的核心物...