线程与线程池
1.?????? 線程基礎(chǔ)
Windows中,線程的職責(zé)是對(duì)CPU進(jìn)行虛擬化,可將線程理解為一個(gè)邏輯CPU。Windows為每個(gè)進(jìn)程提供該進(jìn)程專用的線程。
由于線程是對(duì)CPU進(jìn)行虛擬化,使得線程會(huì)產(chǎn)生空間(內(nèi)存耗用)和時(shí)間(上下文切換)上的開(kāi)銷。
1.??????? 空間開(kāi)銷:在默認(rèn)情況下,Windows為每個(gè)線程的用戶模式棧分配1MB內(nèi)存。
2.??????? 時(shí)間開(kāi)銷:在任何給定的時(shí)刻,Windows只將一個(gè)線程分配給一個(gè)CPU。該線程允許運(yùn)行一個(gè)“時(shí)間片”。一旦時(shí)間片到期,Windows就上下文切換到另一個(gè)線程。Windows執(zhí)行一次上下文切換大約需要30毫秒。
結(jié)論:盡可能避免使用線程,但有時(shí)必須使用線程來(lái)提高程序的響應(yīng)速度和執(zhí)行多任務(wù)。
2.?????? 前后臺(tái)線程
在CLR中的線程只有前臺(tái)線程和后臺(tái)線程兩種。一個(gè)進(jìn)程中所有前臺(tái)線程都停止運(yùn)行時(shí),CLR將強(qiáng)制終止所有正在運(yùn)行的后臺(tái)線程,并且不會(huì)拋出異常。只要有一個(gè)前臺(tái)線程在運(yùn)行,應(yīng)用程序的進(jìn)程就在運(yùn)行。所以前臺(tái)線程適合執(zhí)行關(guān)鍵任務(wù),后臺(tái)現(xiàn)在適合執(zhí)行非關(guān)鍵任務(wù)。下面代碼用于說(shuō)明前后臺(tái)線程與進(jìn)程的關(guān)系。
private static void Main(string[] args){//創(chuàng)建專用線程var t = new Thread(ThreadWork){Name = "NewThread1",//指定是否為后臺(tái)線程,修改該屬性驗(yàn)證前后臺(tái)線程與進(jìn)程的關(guān)系IsBackground = false};//創(chuàng)建專用線程 t.Start();Console.WriteLine("進(jìn)程結(jié)束");}private static void ThreadWork(){Console.WriteLine("線程啟動(dòng):" + Thread.CurrentThread.Name);//讓當(dāng)前線程休眠3秒鐘,把線程執(zhí)行權(quán)讓給優(yōu)先級(jí)高的其他線程執(zhí)行,//避免一直占有線程執(zhí)行權(quán)。3秒鐘過(guò)后線程醒來(lái),一定能立即恢復(fù)執(zhí)行。//這是因?yàn)樵谀莻€(gè)時(shí)刻,其它線程可能正在運(yùn)行而且沒(méi)有被調(diào)度為放棄執(zhí)行,除非//1、“醒來(lái)”的線程具有更高的優(yōu)先級(jí)//2、正在運(yùn)行的線程因?yàn)槠渌蚨枞?/span>Thread.Sleep(3000);Console.WriteLine("線程完成" + Thread.CurrentThread.Name);//這個(gè)方法返回后,該專用線程將終止。 }?
3.?????? 線程池
3.1.??? 線程池基礎(chǔ)
由第一節(jié)線程基礎(chǔ)的結(jié)論可知,我們應(yīng)該在保持代碼響應(yīng)能力的同時(shí)創(chuàng)建盡可能少的線程。CLR線程使用Windows的線程處理能力,一個(gè)CLR線程直接對(duì)應(yīng)一個(gè)Windows線程。為了改善創(chuàng)建和銷毀線程帶來(lái)的空間和時(shí)間上的開(kāi)銷,CLR包含代碼來(lái)管理它自己的線程池。可將線程池想象為可由你的應(yīng)用程序使用的一個(gè)線程集合。每個(gè)CLR一個(gè)線程池。
CLR初始化時(shí),線程池中沒(méi)有線程。在內(nèi)部,線程池維護(hù)一個(gè)操作請(qǐng)求隊(duì)列。應(yīng)用程序向線程池發(fā)出一個(gè)請(qǐng)求時(shí),如果線程池中沒(méi)有線程,就創(chuàng)建一個(gè)新線程用于處理應(yīng)用程序的請(qǐng)求。當(dāng)線程池中的線程完成任務(wù)后,線程不會(huì)被銷毀,而是返回到線程池中,并且進(jìn)入空閑狀態(tài),等待響應(yīng)另一個(gè)請(qǐng)求。由于線程池中的線程處理完任務(wù)后不銷毀自身,所以不再產(chǎn)生額外的性能損失。如果應(yīng)用程序停止向線程池發(fā)出請(qǐng)求,線程池中的線程都處于空閑狀態(tài),一段時(shí)間后,線程會(huì)自己醒來(lái)終止自己并且釋放資源。線程終止自己時(shí)會(huì)產(chǎn)生一定的性能損失,然而,線程池中的線程終止自己是因?yàn)殚e得慌,說(shuō)明應(yīng)用程序本身沒(méi)做什么事,所以這個(gè)性能損失關(guān)系不大。
3.2.??? 線程池管理
不同CLR的版本,其內(nèi)部結(jié)構(gòu)有一定的變化。最好將線程池看成黑盒子。目前,線程池的工作非常理想,強(qiáng)烈建議信任它。
1.??????? 設(shè)置線程池上限
CLR允許開(kāi)發(fā)人員設(shè)置線程池的最大線程數(shù),但永遠(yuǎn)都不應(yīng)該為線程池設(shè)置上限,因?yàn)榭赡馨l(fā)生饑餓或死鎖。由于存在饑餓和死鎖問(wèn)題,所以CLR團(tuán)隊(duì)一直都在穩(wěn)步增加線程池默認(rèn)能夠擁有的最大線程數(shù),目前默認(rèn)值為1000個(gè)線程。
?
注:參考CLR via C#第三版 第25、26章
轉(zhuǎn)載于:https://www.cnblogs.com/jintianzhang/archive/2013/04/10/3013447.html
總結(jié)
- 上一篇: [NOTE]常用Linux命令总结[Th
- 下一篇: sap router maintenan