第一章  為什么要“千頭萬緒”

資源網(wǎng)絡(luò)收集 感謝原創(chuàng)者

轉(zhuǎn)自http://blog.sina.com.cn/s/blog_5678943c0100d4po.html

本章回答了如下幾個問題:

  ◆ 什么是多任務(wù)操作系統(tǒng)?多任務(wù)操作系統(tǒng)有哪些類型?它們有何區(qū)別?

  ◆ 為什么要使用多線程呢?為什么不使用多進(jìn)程?線程、進(jìn)程,它們到底是什么樣的東東?

  ◆ 多線程是如何實現(xiàn)的?線程是如何切換的?效率怎樣?

  ◆ 多線程設(shè)計是如此的誘人,難道什么代價也不用付出?怎樣才能很好地進(jìn)行多線程設(shè)計呢?

 

合作型[cooperative]多任務(wù)和搶先式[preemptive]多任務(wù)有何不同?

兩者的最大區(qū)別是誰來把握CPU的分享。前者由程序員的舉止良好才可做到,后者則由操作系統(tǒng)決定,可以強迫應(yīng)用程序把CPU分享給別人。

Microsoft Windows的前三個版本(123)屬于合作型多任務(wù)操作系統(tǒng),Windows4.0(即Windows95后均屬于強先式多任務(wù)操作系統(tǒng)。

 記住:一個永遠(yuǎn)有反映的UIUser Interface)是很重要的。

 線程和進(jìn)程有何不同?

Win32的角度看,進(jìn)程擁有內(nèi)存和資源。資源則包括核心對象(如文件句柄和線程)、用戶資源(如對話框和字符串)、GDI資源(如Device Contextbrushes)。

進(jìn)程本身并不能夠執(zhí)行,它只是提供一個安置內(nèi)存和線程的地方。(進(jìn)程就是一大堆對象的擁有權(quán)的集合。也就是說,進(jìn)程可以擁有內(nèi)存上下文、文件句柄、線程及一大串DLL模塊(被載入到這一進(jìn)程地址空間中)。

進(jìn)程和內(nèi)存并沒有真正什么事情。一旦CPU開始執(zhí)行代碼,你就擁有了一個線程。在同一時間同一進(jìn)程,你可以擁有一大把線程,執(zhí)行同一段代碼

 為什么不使用多個進(jìn)程?

較之進(jìn)程,線程輕便、價廉,啟動速度快,退出比較快,對系統(tǒng)資源的沖擊比較小。

如果使用多進(jìn)程,最困難的問題是如何把窗口句柄交給另一個進(jìn)程。在Win32中,句柄只在其誕生地(進(jìn)程中)才有意義。這是一種安全警戒,避免某個進(jìn)程有意無意地危及到另一個進(jìn)程的資源。

為了分享窗口句柄,你必須明明白白地產(chǎn)生該句柄的一個副本,并且可以被其他進(jìn)程使用。在一個多線程程序中,所有線程都可以使用這個窗口的句柄,因為句柄和線程生活在同一個進(jìn)程中

 如果兩個線程分屬不同的進(jìn)程,那它們通常沒有辦法共享任何內(nèi)存。不同進(jìn)程間如果要通訊,唯有依賴特別的設(shè)計,使之擁有共享內(nèi)存(shared memory)。

如果兩線程屬于同一進(jìn)程,它們將共享所有的內(nèi)存(包括全局變量、靜態(tài)變量)。

Context SwitchingContext Switch效率

要切換不同的線程,操作系統(tǒng)應(yīng)先切換該線程所隸屬之進(jìn)程的內(nèi)存,然后恢復(fù)該線程存放在CONTEXT結(jié)構(gòu)中的寄存器值。此過程稱為context switch

注:CONTEXT結(jié)構(gòu)中保存了該線程上次被打斷時線程當(dāng)時的狀態(tài),也就是CPU內(nèi)所有寄存器的內(nèi)容。

當(dāng)然,天下沒有免費的午餐,線程切換時都要繳點效率稅金。

對于單CPU而言,搶先式多任務(wù)使電腦看起來可以同時處理多個任務(wù)。但微觀上看,任一時刻,CPU只能做一件事。

CPU的好處是,CPU越多,就有越多線程可以同時執(zhí)行,不需要context switch,從而提高了系統(tǒng)效率。

 競爭條件(Race Conditions)和原子操作Atomic Operations

注意在多任務(wù)操作系統(tǒng)中,一條C指令一定可以安全執(zhí)行完畢,而不在乎context switch是否發(fā)生。

 好消息與壞消息

使用線程并非沒有代價。采用多線程設(shè)計往往會加大程序設(shè)計的復(fù)雜性,必須做到小心精心安排,才能實現(xiàn)預(yù)期目標(biāo)。

成功的秘訣是小心地規(guī)劃:誰要什么?何時要?怎么要?