【轉載】進程和線程

http://www.cnblogs.com/lmule/archive/2010/08/18/1802774.html


簡而言之,一個程序至少有一個進程,一個進程至少有一個線程.
線程的劃分尺度小于進程,使得多線程程序的并發性高。
另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
從邏輯角度來看,多線程的意義在于一個應用程序中,有多個執行部分可以同時執行。但操作系統并沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。
進程是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.
線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.
一個線程可以創建和撤銷另一個線程;同一個進程中的多個線程之間可以并發執行.
進程和線程的主要差別在于它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對于一些要求同時進行并且又要共享某些變量的并發操作,只能用線程,不能用進程。如果有興趣深入的話,我建議你們看看《現代操作系統》或者《操作系統的設計與實現》。對就個問題說得比較清楚。


5.1 簡介


進程(process)是一塊包含了某些資源的內存區域。操作系統利用進程把它的工作劃分為一些功能單元。
進程中所包含的一個或多個執行單元稱為線程(thread)。進程還擁有一個私有的虛擬地址空間,該空間僅能被它所包含的線程訪問。
當運行.NET程序時,進程還會把被稱為CLR的軟件層包含到它的內存空間中。上一章曾經對CLR做了詳細描述。該軟件層是在進程創建期間由運行時宿主載入的(參見4.2.3節)。
線程只能歸屬于一個進程并且它只能訪問該進程所擁有的資源。當操作系統創建一個進程后,該進程會自動申請一個名為主線程或首要線程的線程。主線程將執行運行時宿主, 而運行時宿主會負責載入CLR。
應用程序(application)是由一個或多個相互協作的進程組成的。例如,Visual Studio開發環境就是利用一個進程編輯源文件,并利用另一個進程完成編譯工作的應用程序。
在Windows NT/2000/XP操作系統下,我們可以通過任務管理器在任意時間查看所有的應用程序和進程。盡管只打開了幾個應用程序,但是通常情況下將有大約30個進程同時運行。 事實上,為了管理當前的會話和任務欄以及其他一些任務,系統執行了大量的進程。


5.2 進程


5.2.1 簡介


在運行于32位處理器上的32位Windows操作系統中,可將一個進程視為一段大小為4GB(232字節)的線性內存空間,它起始于0x00000000結束于0xFFFFFFFF。這段內存空間不能被其他進程所訪問,所以稱為該進程的私有空間。這段空間被平分為兩塊,2GB被系統所有,剩下2GB被用戶所有。
如果有N個進程運行在同一臺機器上,那么將需要N×4GB的海量RAM,還好事實并非如此。
Windows是按需為每個進程分配內存的,4GB是32位系統中一個進程所占空間的上限。
將進程所需的內存劃分為4KB大小的內存頁,并根據使用情況將這些內存頁存儲在硬盤上或加載到RAM中,通過系統的這種虛擬內存機制,我們可以有效地減少對實際內存的需求量。當然這些對用戶和開發者來說都是透明的。


5.2.2 System.Diagnostics.Process類


System.Diagnostics.Process類的實例可以引用一個進程,被引用的進程包含以下幾種。
該實例的當前進程。
本機上除了當前進程的其他進程。
遠程機器上的某個進程。
通過該類所包含的方法和字段,可以創建或銷毀一個進程,并且可以獲得一個進程的相關信息。下面將討論一些使用該類實現的常見任務。


5.2.3 創建和銷毀子進程


下面的程序創建了一個稱為子進程的新進程。在這種情況下,初始的進程稱為父進程。子進程啟動了一個記事本應用程序。父進程的線程在等待1秒后銷毀該子進程。該程序的執行效果就是打開并關閉記事本。
例5-1


靜態方法Start()可以使用已存在的Windows文件擴展名關聯機制。例如,我們可以利用下面的代碼執行同樣的操作。


默認情況下,子進程將繼承其父進程的安全上下文。但還可以使用Process.Start()方法的一個重載版本在任意用戶的安全上下文中啟動該子進程,當然需要通過一個System.Diagnostics. ProcessStartInfo類的實例來提供該用戶的用戶名和密碼。


5.2.4 避免在一臺機器上同時運行同一應用程序的多個實例


有些應用程序需要這種功能。實際上,通常來說在同一臺機器上同時運行一個應用程序的多個實例并沒有意義。
直到現在,為了在Windows下滿足上述約束,開發者最常用的方法仍然是使用有名互斥體(named mutex)技術(參見5.7.2節)。然而采用這種技術來滿足上述約束存在以下缺點:
該技術具有使互斥體的名字被其他應用程序所使用的較小的、潛在的風險。在這種情況下該技術將不再有效并且會造成很難檢測到的bug。
該技術不能解決我們僅允許一個應用程序產生N個實例這種一般的問題。
幸而在System.Diagnostics.Process類中擁有GetCurrentProcess()(返回當前進程)和GetPro- cesses()(返回機器上所有的進程)這樣的靜態方法。在下面的程序中我們為上述問題找到了一個優雅且簡單的解決方案。
例5-2


通過方法參數指定了遠程機器的名字后,GetProcesses()方法也可以返回遠程機器上所有的進程。


5.2.5 終止當前進程


可以調用System.Environment類中的靜態方法Exit(int exitCode)或FailFast(stringmessage)終止當前進程。Exit()方法是最好的選擇,它將徹底終止進程并向操作系統返回指定的退出代碼值。之所以稱為徹底終止是因為當前對象的所有清理工作以及finally塊的執行都將由不同的線程完成。當然,終止進程將花費一定的時間。
顧名思義,FailFast()方法可以迅速終止進程。Exit()方法所做的預防措施將被它忽略。只有一個包含了指定信息的嚴重錯誤會被操作系統記錄到日志中。你可能想要在探查問題的時候使用該方法,因為可以將該程序的徹底終止視為數據惡化的起因。


5.3 線程


5.3.1 簡介


一個線程包含以下內容。
一個指向當前被執行指令的指令指針;
一個棧;
一個寄存器值的集合,定義了一部分描述正在執行線程的處理器狀態的值;
一個私有的數據區。
所有這些元素都歸于線程執行上下文的名下。處在同一個進程中的所有線程都可以訪問該進程所包含的地址空間,當然也包含存儲在該空間中的所有資源。
我們不準備討論線程在內核模式或者用戶模式執行的問題。盡管.NET以前的Windows一直使用這兩種模式,并且依然存在,但是對.NET Framework來說它們是不可見的。
并行使用一些線程通常是我們在實現算法時的自然反應。實際上,一個算法往往由一系列可以并發執行的任務組成。但是需要引起注意的是,使用大量的線程將引起過多的上下文切換,最終反而影響了性能。
同樣,幾年前我們就注意到,預測每18個月處理器運算速度增加一倍的摩爾定律已不再成立。處理器的頻率停滯在3GHz~4GHz上下。這是由于物理上的限制,需要一段時間才能取得突破。同時,為了在性能競爭中不會落敗,較大的處理器制造商如AMD和Intel目前都將目標轉向多核芯片。因此我們可以預計在接下去的幾年中這種類型的架構將廣泛被采用。在這種情況下,改進應用性能的唯一方案就是合理地利用多線程技術。


5.3.2 受托管的線程與 Windows線程


必須要了解,執行.NET應用的線程實際上仍然是Windows線程。但是,當某個線程被CLR所知時,我們將它稱為受托管的線程。具體來說,由受托管的代碼創建出來的線程就是受托管的線程。如果一個線程由非托管的代碼所創建,那么它就是非托管的線程。不過,一旦該線程執行了受托管的代碼它就變成了受托管的線程。
一個受托管的線程和非托管的線程的區別在于,CLR將創建一個System.Threading.Thread類的實例來代表并操作前者。在內部實現中,CLR將一個包含了所有受托管線程的列表保存在一個叫做ThreadStore地方。
CLR確保每一個受托管的線程在任意時刻都在一個AppDomain中執行,但是這并不代表一個線程將永遠處在一個AppDomain中,它可以隨著時間的推移轉到其他的AppDomain中。關于AppDomain的概念參見4.1。
從安全的角度來看,一個受托管的線程的主用戶與底層的非托管線程中的Windows主用戶是無關的。


5.3.3 搶占式多任務處理


我們可以問自己下面這個問題: 我的計算機只有一個處理器,然而在任務管理器中我們卻可以看到數以百計的線程正同時運行在機器上!這怎么可能呢?
多虧了搶占式多任務處理,通過它對線程的調度,使得上述問題成為可能。調度器作為Windows內核的一部分,將時間切片,分成一段段的時間片。這些時間間隔以毫秒為精度且長度并不固定。針對每個處理器,每個時間片僅服務于單獨一個線程。線程的迅速執行給我們造成了它們在同時運行的假象。我們在兩個時間片的間隔中進行上下文切換。該方法的優點在于,那些正在等待某些Windows資源的線程將不會浪費時間片,直到資源有效為止。
之所以用搶占式這個形容詞來修飾這種多任務管理方式,是因為在此種方式下線程將被系統強制性中斷。那些對此比較好奇的人應該了解到,在上下文切換的過程中,操作系統會在下一個線程將要執行的代碼中插入一條跳轉到下一個上下文切換的指令。該指令是一個軟中斷,如果線程在遇到這條指令前就終止了(例如,它正在等待某個資源),那么該指定將被刪除而上下文切換也將提前發生。
搶占式多任務處理的主要缺點在于,必須使用一種同步機制來保護資源以避免它們被無序訪問。除此之外,還有另一種多任務管理模型,被稱為協調式多任務管理,其中線程間的切換將由線程自己負責完成。該模型普遍認為太過危險,原因在于線程間的切換不發生的風險太大。如我們在4.2.8節中所解釋的那樣,該機制會在內部使用以提升某些服務器的性能,例如SQL Server2005。但Windows操作系統僅僅實現了搶占式多任務處理。


?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,804評論 18 139
  • 又來到了一個老生常談的問題,應用層軟件開發的程序員要不要了解和深入學習操作系統呢? 今天就這個問題開始,來談談操...
    tangsl閱讀 4,152評論 0 23
  • 托管 vs. 原生線程 托管代碼在“托管線程”上執行,(托管線程)與操作系統提供的原生線程不同。原生線程是在物理機...
    懿民閱讀 708評論 0 5
  • 七月,已經離我們很遠了……還是蠻懷念的,如今的我們已經回不到過去了……
    玥天閱讀 271評論 0 0
  • 標題就像是一件商品的標簽一樣,標簽很重要的作用就是告訴顧客這件商品的基本信息(名稱、功效、價格、產地等),對于標題...
    零叫獸閱讀 23,796評論 0 3