多執行緒程式設計學習筆記 執行緒同步(一)

2022-02-09 07:43:28 字數 4069 閱讀 4508

)中的示例**十,一樣如果多執行緒使用共享變數,就會涉及到乙個執行緒同步的問題。那如何解決呢?

方法有三:

1)        重構程式,移除多執行緒的共享變數,讓乙個執行緒只訪問乙個自有變數

2)        使用原子操作,乙個操作只占用乙個量子時間,一次完成,只有當當前操作完成之後,其他執行緒才能進行操作。這樣可以避免使用獨佔鎖,避免死鎖。

3)        通過net構架提供的mutex、autorestevent、countdowneven、spinwait等類,來進行執行緒間的同步。

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

using system.threading; //

引入執行緒

using

system.diagnostics;

namespace

threadsynchronousdemo

", c.count));

console.writeline(

"----------------------------");

var c1 = new

counterinterlocked();

var t4 = new thread(() =>count(c1));

t4.name = "

執行緒4";

var t5 = new thread(() =>count(c1));

t5.name = "

執行緒5"

;

var t6 = new thread(() =>count(c1));

t6.name = "

執行緒6"

; t4.start();

t5.start();

t6.start();

t4.join();

t5.join();

t6.join();

console.writeline(

string.format("

interlocked的多執行緒總計:

二、使用mutex類

1. 接下來我們來學習使用mutex類來實現執行緒間的同步問題。

2. 在程式啟動時,設定initialowner

為false

,這表示如果互斥量已經建立,則允許程式獲取互斥量。如果沒有互斥量,則程式直接執行,等待接收任意鍵,然後釋放互斥量。

3.**如下: 

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

using system.threading; //

引入執行緒

using

system.diagnostics;

namespace

threadsynchronousdemo

else

}

console.read();}}

}

4.執行結果如下圖。

在debug目錄下,先執行主程式,如上圖中1,則程式1正常執行,此時如果再次開啟debug目錄下的應用主程式,則執行結果如上圖中2。說明互斥量起作用了。

5.先在上圖主程式1中輸入k,然後回車,結果如下圖中3。我們從debug目錄下,再次開啟應用程式,則應用程式的執行結果如下圖中4。說明主程式1,已經把互斥量釋放。

注意:具名互斥量是全域性的作業系統物件。請務必正確關閉互斥量。最好使用using來包裹互斥量**。這種方式可以在不同程式中同步執行緒。

三、使用semaphoreslim類

semaphoreslim是semaphore類的乙個輕量級版本。此類限制了同時訪問同一資源的執行緒數量。

在.net中,類semaphore封裝了clr中的核心同步物件。與標準的排他鎖物件(monitor,mutex,spinlock)不同的是,它不是乙個排他的鎖物件,它與semaphoreslim,readerwritelock等一樣允許多個有限的執行緒同時訪問共享記憶體資源。

semaphore就好像乙個柵欄,有一定的容量,當裡面的執行緒數量到達設定的最大值時候,就沒有執行緒可以進去。然後,如果乙個執行緒工作完成以後出來了,那下乙個執行緒就可以進去了。semaphore的waitone或release等操作分別將自動地遞減或者遞增訊號量的當前計數值。當執行緒試圖對計數值已經為0的訊號量執行waitone操作時,執行緒將阻塞直到計數值大於0。在構造semaphore時,最少需要2個引數。訊號量的初始容量和最大的容量。

1.程式**

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

using system.threading; //

引入執行緒

using

system.diagnostics;

namespace

threadsynchronousdemo

console.read();

}static

void accessdatabase(string name,int

seconds)

等待訪問資料庫

", name);

semapslim.wait();

console.writeline(

" 被授予對資料庫的訪問許可權

", name);

thread.sleep(timespan.fromseconds(seconds));

console.writeline(

" 完成了

", name);

semapslim.release(); }}

}

2.程式執行結果如下圖。

當程式啟動時,建立了乙個semaphoreslim物件,並在建構函式中指定了併發的執行緒數量,然後啟動了10個不同名稱,不同初始執行時間的執行緒。

每個執行緒都嘗試獲取資料庫訪問許可權,但是我們使用semaphoreslim物件做了限制,只有5個執行緒能同時訪問資料庫,當前5個執行緒獲取了資料庫訪問許可權之後,剩下的5個執行緒只能等待,直到有執行緒完成工作,並呼叫semaphore的release方法。

多執行緒程式設計學習筆記 執行緒同步(二)

1.使用autoresetevent類來實現從乙個執行緒向另乙個執行緒發出通知。2.如下 using system using system.collections.generic using system.linq using system.text using system.threading ...

多執行緒程式設計 執行緒同步

同步,永遠是多執行緒程式設計中最核心和最重要的話題.同步相關的概念比如 臨界區,原子操作,以及互斥量等等 總的來說,在多個執行緒之間採取同步措施,無非是為了讓他們更好的協同工作或者維持共享資料的一致性.1.共享資料的一致性 實際上,保證共享資料一致性的最簡單且最好的方法,就是使得該資料成為乙個常量,...

多執行緒程式設計學習筆記 執行緒池(一)

接上文 多執行緒程式設計學習筆記 執行緒同步 一 接上文 多執行緒程式設計學習筆記 執行緒同步 二 接上文 多執行緒程式設計學習筆記 執行緒同步 三 建立多執行緒操作是非常昂貴的,所以每個執行時間非常短的操作,建立多執行緒進行操作,可能並不能提高效率,反而降低了效率。執行緒池,就是我們先分配一些資源...