進程和線程的區別

1. 基本概念

作業:用戶在一次解決或是一個事務處理過程中要求計算機系統所做的工作的集合,它包括用戶程序、所需要的數據集控制命令等。作業是由一系列有序的步驟組成的。作業的完成要經過作業提交、作業收容、作業執行和作業完成4個階段。在執行一個作業可能會運行多個不同的進程。

進程:程序在一個數據集上的一次運行過程。是操作系統資源分配的基本單位。

           在Windows下,進程又被細化爲線程,也就是一個進程下有多個能獨立運行的更小的單位.  進程還擁有一個私有的虛擬地址空間,該空間僅能被它所包含的線程訪問。

線程:是進程中的一個實體,是被操作系統獨立調度和執行的基本單位。一個進程包含一個或多個線程。

              線程只能歸屬於一個進程並且它只能訪問該進程所擁有的資源。當操作系統創建一個進程後,該進程會自動申請一個名爲主線程或首要線程的線程。主線程將執行運行時宿主, 而運行時宿主會負責載入CLR。

簡單總結:

作業是向計算機提交任務的任務實體,

而進程是執行實體,是資源分配的基本單位,

線程是處理機調度的基本單位。

  

2. 進程

2.1 進程的概念主要有兩點:

        第一,進程是一個實體。每一個進程都有它自己的地址空間,一般情況下,包括文本區域(text region)、數據區域(data region)和堆棧(stack region)。文本區域存儲處理器執行的代碼;數據區域存儲變量和進程執行期間使用的動態分配的內存;堆棧區域存儲着活動過程調用的指令和本地變量。

       第二,進程是一個“執行中的程序”。程序是一個沒有生命的實體,只有處理器賦予程序生命時,它才能成爲一個活動的實體,我們稱其爲進程。

2.2 進程特徵  

        動態性:進程的實質是程序在多道程序系統中的一次執行過程,進程是動態產生,動態消亡的。

  併發性:任何進程都可以同其他進程一起併發執行

  獨立性:進程是一個能獨立運行的基本單位,同時也是系統分配資源和調度的獨立單位;

  異步性:由於進程間的相互制約,使進程具有執行的間斷性,即進程按各自獨立的、不可預知的速度向前推進

  結構特徵:進程由程序、數據和進程控制塊三部分組成。

  多個不同的進程可以包含相同的程序:一個程序在不同的數據集裏就構成不同的進程,能得到不同的結果;但是執行過程中,程序不能發生改變。

2.3 進程和作業的區別

1、作業是用戶向計算機提交任務的任務實體。在用戶向計算機提交作業後,系統將它放入外存中的作業等待隊列中等待執行。而進程則是完成用戶任務的執行實體,是向系統申請分配資源的基本單位。任一進程,只要它被創建,總有相應的部分存在於內存中。
2、一個作業可由多個進程組成,且必須至少由一個進程組成,反過來則不成立。
3、作業的概念主要用在
批處理系統中,像UNIX這樣的分時系統中就沒有作業的概念。而進程的概念則用在幾乎所有的多道程序系統中

2.4 進程和程序的區別

1、程序是靜態概念,本身可以作爲一種軟件資源保存;而進程是程序的一次執行過程,是動態概念,它有一定的生命期,是動態地產生和消亡的。

2、進程是一個能獨立運行的單位,能與其他進程併發執行,進程是作爲資源申請和調度單位存在的;而通常的程序段不能作爲一個獨立運行的單位。

3、程序和進程無一一對應關係。一方面一個程序可由多個進程共用;另一方面,一個進程在活動中又可順序地執行若干個程序。 

2.3 進程的狀態

      進程執行時的間斷性,決定了進程可能具有多種狀態。事實上,運行中的進程可能具有以下三種基本狀態。

  1)就緒狀態(Ready):

  進程已獲得除處理器外的所需資源,等待分配處理器資源;只要分配了處理器進程就可執行。就緒進程可以按多個優先級來劃分隊列。例如,當一個進程由於時間片用完而進入就緒狀態時,排入低優先級隊列;當進程由I/O操作完成而進入就緒狀態時,排入高優先級隊列。

  2)運行狀態(Running):

  進程佔用處理器資源;處於此狀態的進程的數目小於等於處理器的數目。在沒有其他進程可以執行時(如所有進程都在阻塞狀態),通常會自動執行系統的空閒進程。

  3)阻塞狀態(Blocked):

  由於進程等待某種條件(如I/O操作或進程同步),在條件滿足之前無法繼續執行。該事件發生前即使把處理機分配給該進程,也無法運行。

             

   

                                     進程狀態的轉換

進程狀態五態模型:
運行狀態(Running)當一個進程正在處理機上運行時。
就緒狀態(Ready)一個進程獲得了除處理機之外的一切所需資源,一旦得到處理機即可運行.
等待狀態又稱阻塞狀態(Blocked)一個進程正在等待某一事件而暫停運行時。如等待某資源,等待輸入/輸出完成。
創建狀態(NEW)一個進程正在被創建,還沒被轉到就緒狀態之前的狀態。
結束狀態(Exit)一個進程正在從系統中消失時的狀態,這是因爲進程結束或由於其他原因所導致。

 

                                                 

                                                        狀態變化圖

 

2.5 Windows 和linux進程

      進程創建:WINDOWS:WIN32接口,函數CreateProcess。Linux:FORK函數,父子進程的區別PPID和PID。

       LINUX中的進程的含義和WINDOWS中是不一樣的。LINUX中的進程本身是可以執行的。而WINDOWS中,進程只是表示一個資源的擁有體,是不能執行的。要執行的話,一定需要一個線程。這也部分解釋了爲什麼CreateProcess中爲啥一定要傳入要執行的文件的名字。LINUX子進程直接使用父親的地址空間,只有子進程加載一個新的可執行文件的時候才創建自己的地址空間。也就是很多時候共享地址空間,有個函數(忘了)就是如果決定開始寫入,則將資源拷貝一份;如果此時突然決定不需要寫入,此時就能避免系統資源的消耗。

      進程相對於WINDOWS中的線程,所以同WINDOWS中的線程創建相比,二者的開銷應該差不多。

      執行:LINUX:exec, WNDOWS:WIN32函數CreateProcess。

      底層:兩者大部分都是C和彙編,在我們看來以爲LINUX全是C,WINDOWS是C++,其實不然操作硬件的是彙編和C。

      使用了不少宏定義,簡化地址運算和程序結構,如定義一個空地址:0x000000表示NULL。

      內核

             WINDOWS:相對穩定的API,就是向後兼容,我們總是看到兼容的字眼。升級方便,過於臃腫。複雜的繼承關係,藏得結結實實的代碼。

             LINUX:不固定的接口,爲了更加的技術化,所以LINUX一直改進,很多時候偏離了桌面用戶。頭文件和執行文件也就是一些算法的改進和函數改進。如果你看完2.4的內核後,再看2.6的內核差異不大,但是不少。升級複雜,考慮的東西太多。數不盡的代碼,代碼是寶貴的,又是該死的。

     進程算法(優先級):

              LINUX:圖形界面少點,內核支持搶佔的同時又支持CFS公平調度算法。二叉樹、紅黑樹等算法。

              WINDOWS:進程假死現象普遍,採用阻塞算法,很多時候導致不流暢、卡死。現在win7做了相當大的改進。算法不清楚,以前阻塞編程的不少。內存:基本上兩者差不多,在X86你懂得。

 

       WINDOS裏的進程/線程是繼承自OS/2的。在WINDOS裏,"進程"是指一個程序,而"線程"是一個"進程"裏的一個執行"線索"。從核心上講, WINDOS的多進程與Linux並無多大的區別,在WINDOS裏的線程才相當於Linux的進程,是一個實際正在執行的代碼。但是,WINDOS裏同一個進程裏各個線程之間是共享數據段的。這纔是與Linux的進程最大的不同。


下面這段程序顯示了WINDOS下一個進程如何啓動一個線程。

int g;

DWORD WINAPI ChildProcess( LPVOID lpParameter ){

int i;

for ( i = 1; i <1000; i ++) {

g ++;

printf( "This is Child Thread: %d", g );

}

ExitThread( 0 );

};

void main()

{

int threadID;

int i;

g = 0;

CreateThread( NULL, 0, ChildProcess, NULL, 0, &threadID );

for ( i = 1; i <1000; i ++) {

g ++;

printf( "This is Parent Thread: %d", g );

}

}


在WINDOS下,使用CreateThread函數創建線程,與Linux下創建進程不同,WINDOS線程不是從創建處開始運行的,而是由 CreateThread指定一個函數,線程就從那個函數處開始運行。此程序同前面的UNIX程序一樣,由兩個線程各打印1000條信息。 threadID是子線程的線程號,另外,全局變量g是子線程與父線程共享的,這就是與Linux最大的不同之處。大家可以看出,WINDOS的進程/線程要比Linux複雜,在Linux要實現類似WINDOS的線程並不難,只要fork以後,讓子進程調用ThreadProc函數,並且爲全局變量開設共享數據區就行了,但在WINDOS下就無法實現類似fork的功能了。所以現在WINDOS下的C語言編譯器所提供的庫函數雖然已經能兼容大多數Linux/UNIX的庫函數,但卻仍無法實現fork。


對於多任務系統,共享數據區是必要的,但也是一個容易引起混亂的問題,在WINDOS下,一個程序員很容易忘記線程之間的數據是共享的這一情況,一個線程修改過一個變量後,另一個線程卻又修改了它,結果引起程序出問題。但在Linux下,由於變量本來並不共享,而由程序員來顯式地指定要共享的數據,使程序變得更清晰與安全。


至於WINDOS的"進程"概念,其含義則是"應用程序",也就是相當於UNIX下的exec了。

 

 

2.6 進程通信

      windows的進程間的通信方式有:

      1.文件映射;2. 共享內存(是文件映射的一種特殊情況);3.郵件槽(mailslot)(點對點消息隊列); 4.匿名管道;5;命名管道; 6. 剪貼板;7.動態數據交換;8.對象鏈接與嵌入;9.遠程過程調用;10.動態鏈接庫;11.socket;12.WM_COPYDATA .
       linux進程間通信的方式有:1.管道 2.信號量 3.共享內存 4.消息隊列 5.套接字 6.信號
      windows和linux共有的進程間通信方式:1. 消息(linux中叫做信號) 2. 共享內存  3. 郵槽  4. 管道   5.socket

Windows 進程

在運行於32位處理器上的32位Windows操作系統中,可將一個進程視爲一段大小爲4GB(232字節)的線性內存空間,它起始於0x00000000結束於0xFFFFFFFF。這段內存空間不能被其他進程所訪問,所以稱爲該進程的私有空間。這段空間被平分爲兩塊,2GB被系統所有,剩下2GB被用戶所有。

如果有N個進程運行在同一臺機器上,那麼將需要N×4GB的海量RAM,還好事實並非如此。

  • Windows是按需爲每個進程分配內存的,4GB是32位系統中一個進程所佔空間的上限。
  • 將進程所需的內存劃分爲4KB大小的內存頁,並根據使用情況將這些內存頁存儲在硬盤上或加載到RAM中,通過系統的這種虛擬內存機制,我們可以有效地減少對實際內存的需求量。當然這些對用戶和開發者來說都是透明的。

        在32位Windows中,進程佔據4GB的虛擬地址空間。與它們在MS-DOS和16位Windows操作系統中不同,32位Windows進程是沒有活力的。這就是說,一個32位Windows進程並不執行什麼指令,它只是佔據着4GB的地址空間,此空間中有應用程序EXE文件的代碼和數據

EXE需要的DLL也將它們的代碼的數據裝入到進程的地址空間除了地址空間,進程還佔有某些資源,比如文件、動態內存分配和線程。當進程終止時,在它生命期中創建的各種資源將被清除。
如上所述,進程是沒有活力的,它只是一個靜態的概念

爲了讓進程完成一些工作,進程必須至少佔有一線程,所以線程是描述進程內的執行,正是線程負責執行包含在進程的地址空間中的代碼。

實際上,單個進程可能包含幾個線程,它們可以同時執行進程的地址空間中的代碼。
爲了做到這一點,
每個線程有自己的一組CPU寄存器和椎。每個進程至少有一個線址程在執行其地址空間中的代碼,
如果沒有線程執行進程地空間中的代碼,進程也就沒有繼續存在的理由,系統將自動清除進程及其地址空間。
爲了運行所有這些線程,操作系統爲每個獨立線程安排一些CPU時間,操作系統以輪轉方式向線程提供時間片,這就給人一種假象,好象這些線程都在同時運行。
創建一個32位Windows進程時,它的第一個線程稱爲主線程,由系統自動生成,然後可由這個主線程生成額外的線程,這些線程又可生成更多的線程。

 

 

3. 線程

3.1 線程的引入

(1)創建進程。系統在創建進程時,必須爲之分配其所必需的、除處理機以外的所有資源。如內存空間、I/O設備以及建立相應的PCB結構。

(2)撤消進程。系統在撤消進程時,又必須先對這些資源進行回收操作,然後再撤消PCB結構。

(3)進程切換。在對進程進行切換時,由於要保留當前進程的CPU環境和設置新選中進程的CPU環境,爲此需花費不少處理機時間。

3.2 線程特徵:

1、線程的執行狀態包括運行、就緒和等待。

2、進程中的所有線程共享所屬進程內的主存和其他資源。

3、擁有自己的線程控制塊和執行棧,寄存器。

3.3 線程屬性

多線程OS中,通常是在一個進程中包括多個線程,每個線程都是作爲利用CPU的基本單位,是花費最小開銷的實體。線程具有以下屬性。

  1)輕型實體

  線程中的實體基本上不擁有系統資源,只是有一點必不可少的、能保證獨立運行的資源,比如,在每個線程中都應具有一個用於控制線程運行的線程控制塊TCB,用於指示被執行指令序列的程序計數器、保留局部變量、少數狀態參數和返回地址等的一組寄存器堆棧

  2)獨立調度和分派的基本單位。

  在多線程OS中,線程是能獨立運行的基本單位,因而也是獨立調度和分派的基本單位。由於線程很“輕”,故線程的切換非常迅速且開銷小。

  3)可併發執行。

  在一個進程中的多個線程之間,可以併發執行,甚至允許在一個進程中所有線程都能併發執行;同樣,不同進程中的線程也能併發執行。

  4)共享進程資源。

  在同一進程中的各個線程,都可以共享該進程所擁有的資源,這首先表現在:所有線程都具有相同的地址空間(進程的地址空間),這意味着,線程可以訪問該地址空間的每一個虛地址;此外,還可以訪問進程所擁有的已打開文件、定時器、信號量機構等。

 

3.4 進程和線程的區別:

       線程和進程的區別在於,子進程和父進程有不同的代碼和數據空間,而多個線程則共享數據空間,每個線程有自己的執行堆棧和程序計數器爲其執行上下文。多線程主要是爲了節約CPU時間,發揮利用,根據具體情況而定。線程的運行中需要使用計算機的內存資源和CPU。

  通常在一個進程中可以包含若干個線程,它們可以利用進程所擁有的資源。在引入線程的操作系統中,通常都是把進程作爲分配資源的基本單位,而把線程作爲獨立運行和獨立調度的基本單位。由於線程比進程更小,基本上不擁有系統資源,故對它的調度所付出的開銷就會小得多,能更高效的提高系統內多個程序間併發執行的程度,從而顯著提高系統資源的利用率和吞吐量。

  因而近年來推出的通用操作系統都引入了線程,以便進一步提高系統的併發性,並把它視爲現代操作系統的一個重要指標。

①、在調度方面,線程是調度和指派的基本單位,而進程是資源擁有的基本單位。在同一進程中,線程的切換不會引起進程切換。在不同的進程中進行線程切換,如一個進程內的線程切換到另一個進程中的線程時,將會引起進程切換。 

②、在擁有資源方面,線程不擁有系統資源,但可以訪問其隸屬進程的系統資源,從而獲得系統資源。 進程間相互獨立,同一進程的各線程間共享。某進程內的線程在其它進程不可見。 

③、在併發性方面,在引入線程的操作系統中,不僅進程之間可以併發執行,而且同一進程內的多線程之間也可併發執行,從而使操作系統具有更好的併發性,大大提高系統的吞吐量。

④、調度切換的系統開銷方面,進程切換時的時空開銷很大,但線程切換時,只需保存和設置少量寄存器內容,因此開銷很小。

另外通信方面,進程間通信IPC,而線程通信由於同一進程內的多個線程共享進程的相同地址空間,線程間可以直接讀寫進程數據段(如全局變量)來進行通信。因此,多線程之間的同步與通信非常容易實現,甚至無須操作系統內核的干預

在多線程OS中,進程不是一個可執行的實體

3.5 引入線程的好處:

    (1) 易於調度。線程佔用內存少,易於切換,可以輕裝運行。

   2) 提高併發性。由於線程佔用內存少,在內存中一次容納的線程就多。這樣有利於提高程序的併發與並行程度。

   (3) 開銷少。創建線程比創建進程開銷少。

   4) 利於充分發揮多處理器功能。在多處理器系統中,一個進程通過創建多個線程,讓每個線程在不同的處理器上運行,進一步提高併發性。

3.6 用戶級線程和內核支持線程較兩種線程的優缺點 :

1.線程的調度與切換速度:內核支持線程的調度和切換與進程的調度和切換十分相似。

 2.系統功能調用:當傳統的用戶進程調用一個系統功能調用時,要由用戶態進入核心態,用戶進程將被阻塞。當內核完成系統調用而返回時,纔將該進程喚醒,繼續執行。  

3.線程執行時間 :對於只設置了用戶級線程的系統,調度是以進程爲單位進行的。在採用輪轉調度算法時,各個進程輪流執行一個時間片,這對諸進程而言似乎是公平的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章