使用EventWaitHandle控制線程間的同步

2021-04-14 05:22:08 字數 2741 閱讀 6450

eventwaithandle 提供了自動(eventresetmode.autoreset)和手動(eventresetmode.manualreset)兩種方式,其主要區別是否自動將同步狀態設定為非終止狀態,以阻塞執行緒。

static void eventwaithandletest2(eventresetmode mode)

} );

t1.start();

r1.set(); }

當我們使用 eventwaithandletest2(eventresetmode.autoreset); 呼叫該方法時,我們發現迴圈體在執行一次後並沒有繼續,執行緒被阻塞。而 eventwaithandletest2(eventresetmode.manualreset); 呼叫時則不會阻塞,迴圈體無限執行下去。由此我們可以區別這兩種狀態的不同,自動方式會自動將同步狀態設定為非終止,而手動則不會。自動狀態時,我們刪除 r1.set(); 行的注釋字元 (//),將狀態重置為終止狀態,則迴圈體自動進行下一輪執行;手動方式,我們將 r1.reset(); 行的注釋行刪除,那麼同步狀態會被重置為非終止狀態狀態,那麼執行緒體自然被阻塞,不會繼續迴圈體的執行了。

.net framework 2.0 的 autoresetevent 和 manualresetevent 繼承自 eventwaithandle,而不是 1.x 中繼承自 waithandle。這兩個類只是重寫了構造方法而已。

public autoresetevent(bool initialstate) : base(initialstate, eventresetmode.autoreset)

public manualresetevent(bool initialstate) : base(initialstate, eventresetmode.manualreset)

接下來,我們另寫乙個例子。讓兩個執行緒交替執行。

using system;

using system.collections.generic;

using system.text;

using system.diagnostics;

using system.threading;

} );

thread t2 = new thread(delegate()

} );

t1.start();

t2.start();

r1.set(); }

static void main()

} }我們為什麼要用2個同步物件呢?試想如果用乙個的話在執行完 t1 的迴圈體 r1.set(); **時,cpu 分配給 t1 的時間片斷可能還沒有超時,那麼自然不會把執行權交給 t2,因為會繼續執行 t1 的迴圈體**,因此用 2 個則可以避免這種問題。

不是執行緒的非終止狀態是事件的非終止狀態,

autoresetevent形象說就像乙個水龍頭一樣,當你關閉水龍頭,狀態就是關閉(終止狀態),所有的水都在裡面等待流出來,當水龍頭開啟,就傳送乙個事件說裡面的水可以出來了,這時就是非終止狀態,一般是用來同步訪問資源

autoresetevent類的物件,如manualresetevent物件一樣,大家可以把它簡單地理解為乙個訊號燈,使用autoresetevent.set()方法可以設定它為有訊號狀態,而使用autoresetevent.reset()方法把它設定為無訊號狀態。這裡用它的有訊號狀態來表示乙個執行緒的結束。

以乙個例子(以執行緒)來說:

控制多個執行緒相互之間的聯絡呢?例如我要到餐廳吃飯,在吃飯之前我先得等待廚師把飯菜做好,之後我開始吃飯,吃完我還得付款,付款方式可以是現金,也可以是信用卡,付款之後我才能離開。分析一下這個過程,我吃飯可以看作是主線程,廚師做飯又是乙個執行緒,服務員用信用卡收款和收現金可以看作另外兩個執行緒,大家可以很清楚地看到其中的關係——我吃飯必須等待廚師做飯,然後等待兩個收款執行緒之中任意乙個的完成,然後我吃飯這個執行緒可以執行離開這個步驟,於是我吃飯才算結束了。事實上,現實中有著比這更複雜的聯絡,我們怎樣才能很好地控制它們而不產生衝突和重複呢?

這種情況下,我們需要用到互斥物件,即system.threading命名空間中的mutex類。大家一定坐過計程車吧,事實上我們可以把mutex看作乙個計程車,那麼乘客就是執行緒了,乘客首先得等車,然後上車,最後下車,當乙個乘客在車上時,其他乘客就只有等他下車以後才可以上車。而執行緒與mutex物件的關係也正是如此,執行緒使用mutex.waitone()方法等待mutex物件被釋放,如果它等待的mutex物件被釋放了,它就自動擁有這個物件,直到它呼叫mutex.releasemutex()方法釋放這個物件,而在此期間,其他想要獲取這個mutex物件的執行緒都只有等待。

下面這個例子使用了mutex物件來同步四個執行緒,主線程等待四個執行緒的結束,而這四個執行緒的執行又是與兩個mutex物件相關聯的。其中還用到autoresetevent類的物件,如同上面提到的manualresetevent物件一樣,大家可以把它簡單地理解為乙個訊號燈,使用autoresetevent.set()方法可以設定它為有訊號狀態,而使用autoresetevent.reset()方法把它設定為無訊號狀態。這裡用它的有訊號狀態來表示乙個執行緒的結束。

// mutex.cs

using system;

using system.threading;

public class mutexsample

public void t1start( )

public void t2start( )

public void t3start( )

public void t4start( )

}

使用GraphEdit使用

1 註冊元件。其實乙個filter就是乙個com元件,所以使用之前需要註冊,可以有兩種方法對元件進行註冊。1.直接使用命令。命令列下輸入 regsvr32 hqtlystd.ax 編譯之後你會在工程目錄下的debug中找到hqtlystd.ax,這個就是要用的filter 即可註冊成功。2.vc6....

MySQL使用學習使用 mysql學習使用

1 mysql學習 1 安裝 ubuntu下直接安裝 apt get install mysql server 2 檢查伺服器是否啟動 sudo netstat tap grep mysql,如果啟動成功,出現以下資訊 tcp00localhost.localdomain mysql listen ...

學習使用CSDN markdown使用

建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 你好!這是你第一次使用markdown編輯器所展示的歡迎頁。如果你想學習如何使用markdown編輯器,可以仔細閱讀這篇文章,了解一下mar...