C 的多執行緒機制探索中

2021-09-05 18:16:42 字數 3216 閱讀 2651

expression代表你希望跟蹤的物件,通常是物件引用。一般地,如果你想保護乙個類的例項,你可以使用this;如果你希望保護乙個靜態變數(如互斥**段在乙個靜態方法內部),一般使用類名就可以了。而statement_block就是互斥段的**,這段**在乙個時刻內只可能被乙個執行緒執行。

using system;

using system.threading;

internal class account

 internal int withdraw(int amount)

//下面的**保證在當前執行緒修改balance的值完成之前

//不會有其他執行緒也執行這段**來修改balance的值

//因此,balance的值是不可能小於0的

lock (this)

 else

}}

internal void dotransactions()

}

internal class test

for (int i = 0; i < 10; i++)

threads[i].name=i.tostring();

for (int i = 0; i < 10; i++)

threads[i].start();

console.readline();

}}

而多執行緒公用乙個物件時,也會出現和公用**類似的問題,這種問題就不應該使用lock關鍵字了,這裡需要用到system.threading中的乙個類monitor,我們可以稱之為監視器,monitor提供了使執行緒共享資源的方案。

monitor類可以鎖定乙個物件,乙個執行緒只有得到這把鎖才可以對該物件進行操作。物件鎖機制保證了在可能引起混亂的情況下乙個時刻只有乙個執行緒可以訪問這個物件。monitor必須和乙個具體的物件相關聯,但是由於它是乙個靜態的類,所以不能使用它來定義物件,而且它的所有方法都是靜態的,不能使用物件來引用。下面**說明了使用monitor鎖定乙個物件的情形:

......

queue oqueue=new queue();

......

monitor.enter(oqueue);

......//現在oqueue物件只能被當前執行緒操縱了

monitor.exit(oqueue);//釋放鎖

如上所示,當乙個執行緒呼叫monitor.enter()方法鎖定乙個物件時,這個物件就歸它所有了,其它執行緒想要訪問這個物件,只有等待它使用monitor.exit()方法釋放鎖。為了保證執行緒最終都能釋放鎖,你可以把monitor.exit()方法寫在try-catch-finally結構中的finally**塊裡。對於任何乙個被monitor鎖定的物件,記憶體中都儲存著與它相關的一些資訊,其一是現在持有鎖的執行緒的引用,其二是乙個預備隊列,佇列中儲存了已經準備好獲取鎖的執行緒,其三是乙個等待佇列,佇列中儲存著當前正在等待這個物件狀態改變的佇列的引用。當擁有物件鎖的執行緒準備釋放鎖時,它使用monitor.pulse()方法通知等待佇列中的第乙個執行緒,於是該執行緒被轉移到預備隊列中,當物件鎖被釋放時,在預備隊列中的執行緒可以立即獲得物件鎖。

下面是乙個展示如何使用lock關鍵字和monitor類來實現執行緒的同步和通訊的例子,也是乙個典型的生產者與消費者問題。這個例程中,生產者執行緒和消費者執行緒是交替進行的,生產者寫入乙個數,消費者立即讀取並且顯示,我將在注釋中介紹該程式的精要所在。用到的系統命名空間如下:

using system;

using system.threading;

首先,我們定義乙個被操作的物件的類cell,在這個類裡,有兩個方法:readfromcell()和writetocell。消費者執行緒將呼叫readfromcell()讀取cellcontents的內容並且顯示出來,生產者程序將呼叫writetocell()方法向cellcontents寫入資料。

public class cell

catch (synchronizationlockexception e)

catch (threadinterruptedexception e)}

console.writeline("consume: ",cellcontents);

readerflag = false; file://重置readerflag標誌,表示消費行為已經完成

monitor.pulse(this); file://通知writetocell()方法(該方法在另外乙個執行緒中執行,等待中)

}return cellcontents;

}public void writetocell(int n)

catch (synchronizationlockexception e)

catch (threadinterruptedexception e)}

cellcontents = n;

console.writeline("produce: ",cellcontents);

readerflag = true;

monitor.pulse(this); file://通知另外乙個執行緒中正在等待的readfromcell()方法

}}

}

下面定義生產者cellprod和消費者類cellcons,它們都只有乙個方法threadrun(),以便在main()函式中提供給執行緒的threadstart**物件,作為執行緒的入口。

public class cellprod

public void threadrun( )

}

public class cellcons

public void threadrun( )

}

然後在下面這個類monitorsample的main()函式中我們要做的就是建立兩個執行緒分別作為生產者和消費者,使用cellprod.threadrun()方法和cellcons.threadrun()方法對同乙個cell物件進行操作。

public class monitorsample

catch (threadstateexception e)

catch (threadinterruptedexception e)

//儘管main()函式沒有返回值,但下面這條語句可以向父程序返回執行結果

environment.exitcode = result;

}}

C 的多執行緒機制探索

c 的多執行緒機制探索 與threadpool類不同,timer類的作用是設定乙個定時器,定時執行使用者指定的函式,而這個函式的傳遞是靠另外乙個 物件timercallback,它必須在建立timer物件時就指定,並且不能更改。定時器啟動後,系統將自動建立乙個新的執行緒,並且在這個執行緒裡執行使用者...

C 的多執行緒機制探索 3 1

c 的多執行緒機制探索 3.1 2007 04 03 15 51 三.執行緒的同步和通訊 生產者和消費者 假 設這樣一種情況,兩個執行緒同時維護乙個佇列,如果乙個執行緒對佇列中新增元素,而另外乙個執行緒從佇列中取用元素,那麼我們稱新增元素的執行緒為生產者,稱取用 元素的執行緒為消費者。生產者與消費者...

C 的多執行緒機制探索4

expression代表你希望跟蹤的物件,通常是物件引用。一般地,如果你想保護乙個類的例項,你可以使用this 如果你希望保護乙個靜態變數 如互斥 段在乙個靜態方法內部 一般使用類名就可以了。而statement block就是互斥段的 這段 在乙個時刻內只可能被乙個執行緒執行。using syst...