仝瑞陽
摘 要:本文闡述了進程、線程概念,描述了進程與線程的關(guān)系;通過我們熟悉的知識競賽場景做類比,能深入淺出地理解操作系統(tǒng)中的進程、線程概念及執(zhí)行過程;以門鑰匙為例生動、形象地詮釋了進程間的通訊、同步與互斥機制;闡述了進程、線程的創(chuàng)建方法以及應(yīng)用特征。
關(guān)鍵詞:進程;線程;并發(fā);共享;資源
0引言
操作系統(tǒng)是應(yīng)用程序(用戶)與計算機硬件的中間層,其管理計算機軟硬件、為用戶提供接口。操作系統(tǒng)的核心是進程、線程的調(diào)度執(zhí)行;為了提高CPU的執(zhí)行效率引入多進程、多線程機制,準確理解進程、線程是掌握操作系統(tǒng)原理的關(guān)鍵。
1進程與線程
進程:是有獨立功能的程序在一個數(shù)據(jù)集合上運行的過程,是一個被操作系統(tǒng)進行資源分配和調(diào)度的一個獨立調(diào)度單位。由機器指令、數(shù)據(jù)、堆棧和控制等部分組成。進程是程序執(zhí)行的過程;進程有就緒、執(zhí)行、阻塞等幾種狀態(tài)。
線程:是CPU調(diào)度和分派的基本單位,它可與同屬一個進程的其他的線程共享進程所擁有的全部資源[1]。
進程和線程的關(guān)系:線程是進程的一部分,一個線程只能屬于一個進程,一個進程可以有多個線程,但至少有一個線程。
進程和線程的區(qū)別:進程是操作系統(tǒng)資源(中央處理器、內(nèi)存、文件、網(wǎng)絡(luò)等)分配的基本單位;線程是任務(wù)調(diào)度和執(zhí)行的基本單位(占用CPU)。每個進程都有獨立的代碼和數(shù)據(jù)空間,線程有獨立的運行棧和程序計數(shù)器,因此進程之間切換開銷大,線程之間切換開銷小,故線程又叫輕量級進程。系統(tǒng)為每個進程分配不同的內(nèi)存空間;線程除CPU外不單獨分配內(nèi)存(使用其所屬進程的資源,線程組共享)。
多進程是多個進程同時存在于內(nèi)存中形成并發(fā)執(zhí)行(不是同時執(zhí)行)。
為理解進程、線程,現(xiàn)舉一我們熟悉的知識競賽場景對照描述:舞臺上有n個隊,每隊有m個隊員進行搶答,搶答器系統(tǒng)對應(yīng)CPU,一個隊對應(yīng)一個進程,一個人對應(yīng)一個線程。此時就相當于有n個進程,每個進程擁有m個線程。
一個隊占有一個搶答臺位相當于一個進程擁有的內(nèi)存空間,m個隊員共享。
某隊員搶答有效進行發(fā)言相當于線程擁有CPU執(zhí)行。
進程調(diào)度:調(diào)度算法有先來先服務(wù)(FCFS)、輪轉(zhuǎn)(RR)、優(yōu)先級、多隊列、多級反饋隊列等。調(diào)度方式有搶占式、非搶占式。隊員爭搶過程相當于非搶占式、先來先服務(wù)進程調(diào)度方法。
2 進程間通信與同步
虛擬內(nèi)存機制(程序運行時以分頁、段方式把一部分部分調(diào)入內(nèi)存[2])為進程管理存儲資源帶來了種種好處,但是也給進程帶來了一些麻煩,因為每個進程擁有獨立的虛擬內(nèi)存地址空間,所以對不同的進程來說一個相同的虛擬地址以為著不同的物理地址。CPU執(zhí)行指令是采用了虛擬地址,對于一個特定的變量來說,對應(yīng)著一個特定的虛擬地址。因此兩個進程不能通過簡單的共享變量的方式來進行通信,只能用信號、管道等方式通信,效率比直接共享內(nèi)存方式差。
進程互斥與同步:多進程并發(fā)執(zhí)行會出現(xiàn)爭用資源,若資源唯一(象獨木橋一次只許一人),就必須對資源使用進行限制,爭用這一資源的進程稱為是互斥關(guān)系,某段時間只能某個進程占用資源。若某兩個或幾個進程執(zhí)行順序先后是確定的不能改變(如生產(chǎn)和消費必須是先生產(chǎn)再消費)稱這兩個進程是同步關(guān)系。
互斥、同步通過信號量機制給以保障。信號量相當于門鎖的鑰匙,互斥相當于只有一把鑰匙,拿到鑰匙者開鎖進門,出來時交出鑰匙,只能一人進門(實現(xiàn)原語操作);同步的實現(xiàn)用兩層信號量,相當于兩道門鎖,第一道門是先后次序(生產(chǎn)先執(zhí)行,消費者看有產(chǎn)品再執(zhí)行)的控制,第二道門實現(xiàn)互斥。
3進程、線程創(chuàng)建
進程創(chuàng)建唯一方法是調(diào)用函數(shù)fork(),該調(diào)用創(chuàng)建一個與原進程代碼完全一樣的子進程,原進程稱為父進程,新進程稱為子進程,父子進程不同的是進程標識號(PID)以及它們的進程控制塊(PCB)中的父子進程標識號記錄字段,通過下面代碼作一說明:
If(fort()==0)
Printf(“I am? son_process\n”);
else
Printf(“I am father_process\n”);
Sleep(1);
執(zhí)行結(jié)果是I am? son_process
I am fathe_rprocess
或者: I am father_process
I am? son_proces
從結(jié)果看if與else中的代碼都完成一次執(zhí)行,說明fort()向父進程返回了不為0的值(即進程的ID)而向子進程返回了0值。
線程創(chuàng)建:C語言利用Pthreads庫創(chuàng)建線程數(shù)據(jù)結(jié)構(gòu),Pthreads運行在用戶空間,內(nèi)核調(diào)度實體(KSE)運行在內(nèi)核空間;Linux內(nèi)核提供clone系統(tǒng)調(diào)用創(chuàng)建類似線程的輕量級進程[3]。
Java中線程的實現(xiàn):Java語言提供了java.lang.Thread類來表示線程,提供了run方法表示線程的運行的邏輯控制流[4]。
4結(jié)語
構(gòu)建并發(fā)程序可以基于進程也可基于線程,現(xiàn)代多任務(wù)操作系統(tǒng)(如WINDOWS)采用時間片輪轉(zhuǎn)調(diào)度的多線程方式,由于切換開銷比進程小,并發(fā)執(zhí)行效率高。
參考文獻:
[1]湯小丹,梁紅兵,哲鳳屏,等. 計算機操作系統(tǒng).4版. 西安:西安電子科技大學出版社, 2019 ,39-40
[2]白中英,戴志濤.計算機組成原理.6版.北京:科學出版社,2019,104-105
[3]邵國金等.Linux操作系統(tǒng).3版.電子工業(yè)出版社,2018,339
[4]軟件開發(fā)技術(shù)聯(lián)盟.Java開發(fā)實戰(zhàn).清華大學出版社,2013,237-238