天天看點

程序和線程的差別、多線程和多程序的差別、為什麼要引入多線程

程序和線程的差別

(1) 線程是輕量級的程序,它的建立和銷毀、上下文切換所需要的時間比程序小得多。

(2) 線程作為排程的基本機關,處理機分給線程,即真正在處理機上運作的是線程。而程序是系統資源配置設定的最小機關。

(3) 線程依賴于程序而存在,一個線程隻能屬于一個程序,一個程序可以有一個線程或者多個線程。

(4) 程序有獨立的位址空間,同一程序下的各個線程之間共享程序的位址空間(包括代碼段、資料集、堆等)及一些程序級的資源(如打開檔案和信号),某程序内的線程在其它程序不可見。

(5) 程序結束後,該程序下的所有線程将銷毀,而一個線程的結束不會影響同一程序下的其他線程。

多線程和多程序的差別

每個線程類似于獨立的程序,隻有一點差別:它們共享位址空間,進而能夠通路相同的資料。

與程序相比,線程之間的上下文切換有一點主要差別:位址空間保持不變(即不需要切換目前使用的頁表)。

為什麼要引入多線程?

下面舉一個例子,來說明引入多線程的好處。

假設使用者正在寫一本書。從作者的觀點來看,最容易的方法是把整本書作為一個檔案,這樣一來,查詢内容、完成全局替換等都非常容易。另一種方法是,把每一章都處理成單獨一個檔案。但是,在把每個小節和子小節都分成單個的檔案之後,若必須對全書進行全局的修改時,那就真是麻煩了,因為有成百個檔案必須一個個地編輯。例如,如果所建議的某個标準××××正好在書影印之前被準許了,于是“标準草案××××”一類的字眼就必須改為“标準××××”。如果整本書是一個檔案,那麼隻要一個指令就可以完成全部的替換處理。相反,如果一本書分成了300個檔案,那麼就必須分别對每個檔案進行編輯。

現在考慮,如果有一個使用者突然在一個有800頁的檔案的第一頁上删掉了一段話之後,會發生什麼情形。在檢查了所修改的頁面并确認正确後,這個使用者現在打算接着在第600頁上進行另一個修改,并鍵入一條指令通知字處理軟體轉到該頁面(可能要查閱隻在那裡出現的一個短語)。于是字處理軟體被強制對整本書的前600頁重新進行格式化處理,這是因為在排列該頁前面的所有頁面之前,字處理軟體并不知道第600頁的第一行應該在哪裡。而在第600頁的頁面可以真正在螢幕上顯示出來之前,計算機可能要拖延相當一段時間,進而令使用者不甚滿意。

多線程在這裡可以發揮作用。假設字處理軟體被編寫成含有兩個線程的程式。一個線程與使用者互動,而另一個在背景重新進行格式處理。一旦在第1頁中的語句被删除掉,互動線程就立即通知格式化線程對整本書重新進行處理。同時,互動線程繼續監控鍵盤和滑鼠,并響應諸如滾動第1頁之類的簡單指令,此刻,另一個線程正在背景瘋狂地運算。如果有點運氣的話,重新格式化會在使用者請求檢視第600頁之前完成,這樣,第600頁頁面就立即可以在螢幕上顯示出來。

如果已經做到了這一步,那麼為什麼不再進一步增加一個線程呢?許多字處理軟體都有每隔若幹分鐘自動在磁盤上儲存整個檔案的特點,用于避免由于程式崩潰、系統崩潰或電源故障而造成使用者一整天的工作丢失的情況。第三個線程可以處理磁盤備份,而不必幹擾其他兩個線程。擁有三個線程的情形,如圖2-7所示。

程式和線程的差別、多線程和多程式的差別、為什麼要引入多線程

如果程式是單線程的,那麼在進行磁盤備份時,來自鍵盤和滑鼠的指令就會被忽略,直到備份工作完成為止。使用者當然會認為性能很差。另一個方法是,為了獲得好的性能,可以讓鍵盤和滑鼠事件中斷磁盤備份,但這樣卻引入了複雜的中斷驅動程式設計模型。如果使用三個線程,程式設計模型就很簡單了。第一個線程隻是和使用者互動;第二個線程在得到通知時進行文檔的重新格式化;第三個線程周期性地将RAM中的内容寫到磁盤上。

很顯然,在這裡用三個不同的程序是不能工作的,這是因為三個線程都需要對同一個檔案進行操作。由于多個線程可以共享公共記憶體,是以通過用三個線程替換三個程序,使得它們可以通路同一個正在編輯的檔案,而三個程序是做不到的。

繼續閱讀