国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C#多線程實(shí)踐——線程同步

2019-11-17 02:23:03
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

C#多線程實(shí)踐——線程同步

  下面的表格列展了.NET對(duì)協(xié)調(diào)或同步線程動(dòng)作的可用的工具:

簡(jiǎn)易阻止方法

構(gòu)成

目的

Sleep

阻止給定的時(shí)間周期

Join

等待另一個(gè)線程完成

鎖系統(tǒng)

構(gòu)成

目的

跨進(jìn)程?

速度

lock

確保只有一個(gè)線程訪問(wèn)某個(gè)資源或某段代碼。

Mutex

確保只有一個(gè)線程訪問(wèn)某個(gè)資源或某段代碼。可被用于防止一個(gè)程序的多個(gè)實(shí)例同時(shí)運(yùn)行。

中等

Semaphore

確保不超過(guò)指定數(shù)目的線程訪問(wèn)某個(gè)資源或某段代碼。

中等

信號(hào)系統(tǒng)

構(gòu)成

目的

跨進(jìn)程?

速度

EventWaitHandle

允許線程等待直到它受到了另一個(gè)線程發(fā)出信號(hào)。

中等

Wait 和 Pulse*

允許一個(gè)線程等待直到自定義阻止條件得到滿足。

中等

同步要領(lǐng)

阻止(Blocking)

  當(dāng)一個(gè)線程通過(guò)上面所列的方式處于等待或暫停的狀態(tài),被稱(chēng)為被阻止。一旦被阻止,線程立刻放棄它被分配的CPU時(shí)間,將它的ThreadState屬性添加為WaitSleepJoin狀態(tài),直到停止阻止。停止阻止由以下任一條件觸發(fā):

  • 阻止的條件已得到滿足
  • 操作超時(shí)(如果timeout被指定了)
  • 通過(guò)Thread.Interrupt中斷了
  • 通過(guò)Thread.Abort放棄了

當(dāng)線程通過(guò)(不建議)Suspend 方法暫停,不認(rèn)為是被阻止了。

休眠 和 輪詢(xún)

  調(diào)用Thread.Sleep阻止當(dāng)前的線程指定的時(shí)間(或者直到中斷):

static void Main() {    Thread.Sleep (0);                           // 釋放CPU時(shí)間片    Thread.Sleep (1000);                        // 休眠1000毫秒    Thread.Sleep (TimeSpan.FromHours (1));      // 休眠1小時(shí)    Thread.Sleep (Timeout.Infinite);            // 休眠直到中斷}

  確切地說(shuō),Thread.Sleep放棄了占用CPU,請(qǐng)求不再被分配時(shí)間直到超過(guò)某個(gè)給定的時(shí)間。Thread.Sleep(0)放棄CPU的時(shí)間剛剛夠其它在時(shí)間片隊(duì)列里的活動(dòng)線程(如果有的話)被執(zhí)行。

Thread.Sleep在阻止方法中是唯一的暫停捕獲Windows Forms程序的Windows消息的方法,在Windows Forms程序中是一個(gè)很大的問(wèn)題,任何對(duì)主UI線程的阻止都將使程序失去相應(yīng)。因此一般避免這樣使用,無(wú)論信息獲取是否被“技術(shù)地”暫定與否。線程類(lèi)同時(shí)也提供了一個(gè)SpinWait方法,它使用輪詢(xún)CPU而非放棄CPU時(shí)間的方式,保持給定的迭代次數(shù)進(jìn)行“無(wú)用地繁忙”。50迭代停頓大約一微秒,一般取決于CPU的速度和負(fù)載。從技術(shù)上講,SpinWait并不是一個(gè)阻止的方法:一個(gè)處于spin-waiting的線程的ThreadState不是WaitSleepJoin狀態(tài),并且也不會(huì)被其它的線程過(guò)早的中斷(Interrupt)。SpinWait很少被使用,它的作用是等待一個(gè)在極短時(shí)間(可能小于一微秒)內(nèi)可準(zhǔn)備好的可預(yù)期的資源,而不用調(diào)用Sleep方法阻止線程而浪費(fèi)CPU時(shí)間。不過(guò),這種技術(shù)的優(yōu)勢(shì)只有在多處理器計(jì)算機(jī):對(duì)單一處理器的電腦,直到輪詢(xún)的線程結(jié)束了它的時(shí)間片之前,一個(gè)資源沒(méi)有機(jī)會(huì)改變狀態(tài),這有違它的初衷。并且調(diào)用SpinWait經(jīng)常會(huì)花費(fèi)較長(zhǎng)的時(shí)間這本身就浪費(fèi)了CPU時(shí)間。

阻止 vs. 輪詢(xún)

線程可以等待某個(gè)確定的條件來(lái)明確輪詢(xún)使用一個(gè)輪詢(xún)的方式,比如:

while (!PRoceed);

或者:

while (DateTime.Now < nextStartTime);

  這是非常浪費(fèi)CPU時(shí)間的:對(duì)于CLR和操作系統(tǒng)而言,線程進(jìn)行了一個(gè)重要的計(jì)算,所以分配了相應(yīng)的資源!在這種狀態(tài)

下的輪詢(xún)線程不算是阻止,不像一個(gè)線程等待一個(gè)EventWaitHandle(一般使用這樣的信號(hào)任務(wù)來(lái)構(gòu)建)。

阻止和輪詢(xún)組合使用可以產(chǎn)生一些變換:

while (!proceed) Thread.Sleep (x); // "輪詢(xún)休眠!"

 x越大,CPU效率越高,折中方案是增大潛伏時(shí)間,任何20ms的花費(fèi)是微不足道的,除非循環(huán)中的條件是極其復(fù)雜的。

除了稍有延遲,這種輪詢(xún)和休眠的方式可以結(jié)合的非常好,可能它最大的用處在于程序員可以放棄使用復(fù)雜的信號(hào)結(jié)構(gòu)來(lái)工作了。

使用Join等待一個(gè)線程完成

可以通過(guò)Join方法阻止線程直到另一個(gè)線程結(jié)束:

class ThreadDemo {     static void Main() {     Thread t = new Thread (delegate() { Console.ReadLine();});     t.Start();     t.Join(); // 等待直到線程完成     Console.WriteLine ("Thread t's ReadLine complete!");     } }

  Join方法也接收一個(gè)使用毫秒或用TimeSpan類(lèi)的超時(shí)參數(shù),當(dāng)Join超時(shí)是返回false,如果線程已終止,則返回true 。

  Join所帶的超時(shí)參數(shù)非常像Sleep方法,實(shí)際上下面兩行代碼幾乎差不多:

Thread.Sleep (1000);
Thread.CurrentThread.Join (1000);

  他們的區(qū)別明顯在于單線程的應(yīng)用程序域與COM互操作性:在阻止時(shí),Join保持信息捕獲,Sleep暫停信息捕獲。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 莱芜市| 潼南县| 莫力| 南昌县| 缙云县| 汪清县| 保亭| 额济纳旗| 景宁| 临西县| 武山县| 津南区| 米泉市| 康定县| 葫芦岛市| 富川| 应用必备| 年辖:市辖区| 西畴县| 上高县| 大英县| 静宁县| 山阴县| 长沙市| 元阳县| 渝中区| 蕉岭县| 黄冈市| 呼玛县| 霍州市| 张家界市| 喀什市| 聂拉木县| 永顺县| 锦屏县| 宜兴市| 尚义县| 蛟河市| 清水县| 晴隆县| 密云县|