黃驊烈士網(wǎng)奇seo培訓(xùn)官網(wǎng)
文章目錄
- 前言
- 一、初識(shí)fork
- 1.演示
- 2.介紹
- 3.將子進(jìn)程與父進(jìn)程執(zhí)行的任務(wù)分離
- 4.多進(jìn)程并行
- 二、進(jìn)程的狀態(tài)
- 1.進(jìn)程的狀態(tài)都有哪些?
- 2.查看進(jìn)程的狀態(tài)
- 2.運(yùn)行(R)
- 3.阻塞
- 4.僵尸進(jìn)程(Z)
- 1.僵尸狀態(tài)概念
- 2.為什么要有僵尸狀態(tài)?
- 3.僵尸狀態(tài)的例子
- 3.僵尸狀態(tài)的危害
- 5.孤兒進(jìn)程
- 三、進(jìn)程的優(yōu)先級(jí)
- 1.優(yōu)先級(jí)概念
- 1.權(quán)限與優(yōu)先級(jí)
- 2.什么是優(yōu)先級(jí)
- 3.為什么存在優(yōu)先級(jí)
- 4.特性
- 2.查看系統(tǒng)進(jìn)程
- 3.PRI和NI
- 4.修改進(jìn)程的優(yōu)先級(jí)
- 總結(jié)
前言
本文介紹了創(chuàng)建進(jìn)程、查看進(jìn)程、進(jìn)程的狀態(tài)以及進(jìn)程的優(yōu)先級(jí)相等關(guān)概念
一、初識(shí)fork
通過(guò)系統(tǒng)調(diào)用fork創(chuàng)建子進(jìn)程。
1.演示
文件test.c
運(yùn)行結(jié)果:
2.介紹
fork的頭文件為unistd.h
fork的返回值:父進(jìn)程會(huì)返回子進(jìn)程的pid,子進(jìn)程返回0(一個(gè)子進(jìn)程只有一個(gè)父進(jìn)程,但是有個(gè)父進(jìn)程可以有無(wú)數(shù)個(gè)子進(jìn)程,一次要將子進(jìn)程的pid返回給父進(jìn)程,而子進(jìn)程不需要)
3.將子進(jìn)程與父進(jìn)程執(zhí)行的任務(wù)分離
根據(jù)父子進(jìn)程的返回值不同:
文件test.c
運(yùn)行結(jié)果:
4.多進(jìn)程并行
文件test.c
運(yùn)行結(jié)果:
二、進(jìn)程的狀態(tài)
1.進(jìn)程的狀態(tài)都有哪些?
進(jìn)程的狀態(tài)有很多:運(yùn)行、就緒、掛起、阻塞等等。
進(jìn)程有這么多不同的狀態(tài),本質(zhì)上是為了滿(mǎn)足不同的運(yùn)行場(chǎng)景。
具體的進(jìn)程狀態(tài):
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
-
R運(yùn)行狀態(tài)(running):并不意味著進(jìn)程一定在運(yùn)行狀態(tài),他只是表明進(jìn)程在運(yùn)行隊(duì)列里。
-
S睡眠狀態(tài)(sleeping):意味著進(jìn)程正在等待時(shí)間完成(這里的睡眠也成為可中斷睡眠/淺度睡眠(interruptible sleep))。
例子:進(jìn)程從運(yùn)行到訪問(wèn)外設(shè)再到訪問(wèn)外設(shè)完畢這段時(shí)間進(jìn)程處于睡眠狀態(tài)。 -
D磁盤(pán)休眠狀態(tài)(Disk sleep):也叫做不可中斷睡眠狀態(tài),該狀態(tài)的進(jìn)程通常會(huì)等待I/O的結(jié)束。該進(jìn)程不能被操作系統(tǒng)kill掉。
例子:某一個(gè)進(jìn)程向磁盤(pán)發(fā)布了寫(xiě)東西的任務(wù)(例如:要求寫(xiě)0~100到文件上),那么磁盤(pán)就會(huì)去完成這個(gè)任務(wù),此時(shí)進(jìn)程處于等待狀態(tài)。如果恰好操作系統(tǒng)內(nèi)的資源緊缺,操作系統(tǒng)有權(quán)利自主殺掉一些不干事情的進(jìn)程(未處于運(yùn)行狀態(tài)),該進(jìn)程就會(huì)被操作系統(tǒng)殺死。由于外設(shè)的運(yùn)行速度很慢,等到外設(shè)完成任務(wù)回來(lái)尋找對(duì)應(yīng)的進(jìn)程交代任務(wù)結(jié)果時(shí),發(fā)現(xiàn)該進(jìn)程無(wú)法被喚醒(該進(jìn)程已經(jīng)被殺死了),這就會(huì)導(dǎo)致磁盤(pán)內(nèi)對(duì)應(yīng)數(shù)據(jù)的丟失。因此,為了避免這種情況出現(xiàn),我們將一些特殊的進(jìn)程賦予D狀態(tài)(相當(dāng)于免死金牌,避免操作系統(tǒng)將它殺死),這樣它只能等對(duì)應(yīng)的I/O完成才會(huì)重新變?yōu)槠渌麪顟B(tài)。 -
T停止?fàn)顟B(tài)(stopped):可以通過(guò)發(fā)送SIGSTOP信號(hào)給進(jìn)程來(lái)停止進(jìn)程(該進(jìn)程處于T狀態(tài)),然后可以給這個(gè)被暫停的狀態(tài)發(fā)送SIGCONT信號(hào),讓該進(jìn)程繼續(xù)運(yùn)行(當(dāng)一個(gè)前臺(tái)進(jìn)程被暫停后,又被恢復(fù)繼續(xù)運(yùn)行時(shí),前臺(tái)進(jìn)程會(huì)轉(zhuǎn)為后臺(tái)進(jìn)程,此時(shí)進(jìn)程無(wú)法被ctrl + c終止,只能用kill -9 (進(jìn)程pid)終止進(jìn)程)。
-
X死亡狀態(tài)(dead):該狀態(tài)只是一個(gè)返回狀態(tài),不會(huì)在任務(wù)列表中看到這個(gè)狀態(tài)。
-
還有兩個(gè)特殊的狀態(tài):僵尸狀態(tài)和孤兒狀態(tài)在后續(xù)內(nèi)容會(huì)詳細(xì)講解。
2.查看進(jìn)程的狀態(tài)
ps aux
或者 ps ajx
命令可以查看進(jìn)程的狀態(tài)。
2.運(yùn)行(R)
- 一個(gè)CPU一個(gè)運(yùn)行時(shí)隊(duì)列;
- 讓進(jìn)程進(jìn)入運(yùn)行時(shí)隊(duì)列,本質(zhì)是將該進(jìn)程的task_struct結(jié)構(gòu)體放入運(yùn)行隊(duì)列中;
- 進(jìn)程PCB在runqueue時(shí),該進(jìn)程就是運(yùn)行狀態(tài)(R),而不是該進(jìn)程在運(yùn)行時(shí)才算;(CPU很快,可以將運(yùn)行隊(duì)列中的進(jìn)程很快的過(guò)一遍,因此運(yùn)行隊(duì)列里都是處于運(yùn)行狀態(tài))
狀態(tài) ->進(jìn)程內(nèi)部的屬性 -> task_struct -> int(1:run ; 2:run ; 3:run ; 4:run),進(jìn)程的狀態(tài)本質(zhì)就是進(jìn)程PCB中的一個(gè)整型值。 - 不要以為只有CPU會(huì)被多進(jìn)程訪問(wèn),硬件設(shè)備也是稀缺資源,也會(huì)被多進(jìn)程訪問(wèn)。
- 所謂的進(jìn)程的不同狀態(tài),本質(zhì)是進(jìn)程在不同的隊(duì)列中等待某種資源(將task_struct結(jié)構(gòu)體對(duì)象放入不同的的等待隊(duì)列)。
3.阻塞
- 外設(shè)硬件的訪問(wèn)速度是很慢的(相對(duì)CPU),但是進(jìn)程或多或少都需要訪問(wèn)它,但是在多進(jìn)程同時(shí)訪問(wèn)硬件設(shè)備時(shí),也只有少量的進(jìn)程(競(jìng)爭(zhēng)力強(qiáng)的)可以訪問(wèn)到它。
- 當(dāng)有其他進(jìn)程在訪問(wèn)該設(shè)備時(shí),其他進(jìn)程只能等待。等待中的進(jìn)程將從運(yùn)行時(shí)隊(duì)列中取出,放入該設(shè)備對(duì)應(yīng)的阻塞(等待)隊(duì)列中,此時(shí)該進(jìn)程處于阻塞狀態(tài)。
- 等到設(shè)備空余出來(lái)(沒(méi)有進(jìn)程訪問(wèn)的時(shí)候),OS會(huì)知道它好了,然后OS就會(huì)等待的該進(jìn)程的狀態(tài)由阻塞改為運(yùn)行(R),在將該進(jìn)程放入運(yùn)行時(shí)隊(duì)列即可機(jī)械運(yùn)行。
4.僵尸進(jìn)程(Z)
1.僵尸狀態(tài)概念
一個(gè)小栗子
一天,張三在路上跑步,突然路邊有一個(gè)人死亡了,張三立刻打電話(huà)給警察局,那么在這個(gè)路人死亡的那一瞬間直到警察查明他的信息以及死亡原因的這一過(guò)程就相當(dāng)于處于僵尸狀態(tài)(死了,但是別人不知道他死了)。
- 當(dāng)子進(jìn)程退出,但是父進(jìn)程沒(méi)有(通過(guò)
wait()
系統(tǒng)調(diào)用)讀取子進(jìn)程的退出狀態(tài)代碼時(shí),就會(huì)導(dǎo)致子進(jìn)程處于僵尸狀態(tài)。 - 僵尸進(jìn)程會(huì)議終止?fàn)顟B(tài)保持在進(jìn)程表中,并且一直等待父進(jìn)程讀取退出狀態(tài)代碼。
- 因此,只要子進(jìn)程退出,父進(jìn)程還在勻稱(chēng)并且沒(méi)有讀取子進(jìn)程的狀態(tài),子進(jìn)程就進(jìn)入僵尸狀態(tài)。
2.為什么要有僵尸狀態(tài)?
進(jìn)程被創(chuàng)建是為了完成分配給他的任務(wù),當(dāng)然生活中有些事情需要返回結(jié)果,有些事情不需要,但是作為一個(gè)程序它無(wú)論你需不需要知道結(jié)果,它都得將任務(wù)的執(zhí)行情況返回。程序退出時(shí)不能立即釋放程序中的所有資源,而是需要保持一段時(shí)間,讓父進(jìn)程/OS讀取它的退出代碼。
退出程序和釋放程序的資源之間的一段時(shí)間程序是處于僵尸狀態(tài)(注意:僵尸狀態(tài)是一個(gè)問(wèn)題),進(jìn)程推出時(shí)沒(méi)有立即回收它的退出代碼。
3.僵尸狀態(tài)的例子
創(chuàng)建一個(gè)子進(jìn)程,讓父進(jìn)程不要退出,并且什么也不干(不回收子進(jìn)程),讓子進(jìn)程退出(exit(0)
頭文件是stdlib.h
),這時(shí)子進(jìn)程就處于僵尸狀態(tài)。
3.僵尸狀態(tài)的危害
- 進(jìn)程的退出狀態(tài)必須被維持下去,因?yàn)樗嬖V它的父進(jìn)程(或者0S),你交給我的任務(wù),我辦的怎么樣了(即,結(jié)果如何)。如果父進(jìn)程一直不讀取,子進(jìn)程就會(huì)一直處于Z狀態(tài)。
- 維持退出狀態(tài)本身也是需要數(shù)據(jù)維護(hù)的,也屬于進(jìn)程的基本信息,因此它是保存在task_struct(PCB)中的。當(dāng)然,如果Z狀態(tài)一直不退出,該P(yáng)CB就要一直被維護(hù)。
- 如果推廣父進(jìn)程創(chuàng)建了很多子進(jìn)程,但是不回收,是不是就會(huì)造成內(nèi)存資源的浪費(fèi)(內(nèi)存泄漏)?
數(shù)據(jù)結(jié)構(gòu)對(duì)象本身就要占內(nèi)存(C中定義一個(gè)結(jié)構(gòu)體變量/對(duì)象,是需要在內(nèi)存的某個(gè)位置開(kāi)辟空間的)
5.孤兒進(jìn)程
那么問(wèn)題來(lái)了,如果父進(jìn)程先退出,子進(jìn)程再退出進(jìn)入Z狀態(tài)后,又該怎么辦呢?
- 父進(jìn)程先退出的話(huà),它的子進(jìn)程就被稱(chēng)為“孤兒進(jìn)程”。
- 孤兒進(jìn)程會(huì)被操作系統(tǒng)的1號(hào)init進(jìn)程領(lǐng)養(yǎng),它的資源由init進(jìn)程回收。
三、進(jìn)程的優(yōu)先級(jí)
1.優(yōu)先級(jí)概念
1.權(quán)限與優(yōu)先級(jí)
權(quán)限是限制是否可以做某事,優(yōu)先級(jí)是限制做某事的順序(先做還是后做)。
2.什么是優(yōu)先級(jí)
- 獲得某個(gè)資源的順序(是先獲得該資源還是后獲得該資源)。
- 優(yōu)先級(jí)和進(jìn)程的狀態(tài)一樣本質(zhì)是是進(jìn)程PCB中的一個(gè)(或幾個(gè))整型數(shù)字,Linux中的優(yōu)先級(jí)是用兩個(gè)整型數(shù)表示的。
3.為什么存在優(yōu)先級(jí)
因?yàn)橘Y源是有限的,但是有很多進(jìn)程都想申請(qǐng)資源。
4.特性
- 競(jìng)爭(zhēng)性:
系統(tǒng)的進(jìn)程眾多,但是CPU資源只有少量(甚至只有一個(gè)),所以進(jìn)程之間是具有競(jìng)爭(zhēng)屬性的。為了高效完成任務(wù),更加合理的競(jìng)爭(zhēng)相關(guān)的資源,便具有了優(yōu)先級(jí)。 - 獨(dú)立性:
多進(jìn)程運(yùn)行需要獨(dú)享各種資源,多進(jìn)程運(yùn)行期間互不干擾。 - 并行:
多個(gè)進(jìn)程在多個(gè)CPU下,同時(shí)進(jìn)行運(yùn)行,這稱(chēng)之為并行。 - 并發(fā):
多個(gè)進(jìn)程在單個(gè)CPU下采用進(jìn)程切換(CPU采用輪轉(zhuǎn)的方式,給每個(gè)進(jìn)程一定的時(shí)間片運(yùn)行,進(jìn)行進(jìn)程切換)的方式,在一段時(shí)間內(nèi)多個(gè)進(jìn)程一同推進(jìn),稱(chēng)之為并發(fā)。
2.查看系統(tǒng)進(jìn)程
在Linux/Unix系統(tǒng)中,用ps -la
命令可以查看進(jìn)程的信息。
UID:該代表執(zhí)行者的身份
PID:該進(jìn)程的代號(hào)
PPID:該進(jìn)程是由哪個(gè)進(jìn)程發(fā)展衍生來(lái)的(即該進(jìn)程的父進(jìn)程的PID)
PRI:該進(jìn)程可被執(zhí)行的優(yōu)先級(jí)
NI:該進(jìn)程的nice值
3.PRI和NI
- PRI:進(jìn)程的優(yōu)先級(jí),該值越小優(yōu)先級(jí)越高;
- NI:進(jìn)程的nice值,表示進(jìn)程可以被執(zhí)行的優(yōu)先級(jí)的修正數(shù)值(調(diào)節(jié)進(jìn)程優(yōu)先級(jí))
- PRI(new) = PRI(old)+ NI;
- 當(dāng)nice值為負(fù)值時(shí),該進(jìn)程的優(yōu)先級(jí)值會(huì)變小,優(yōu)先級(jí)會(huì)變高,越快被執(zhí)行;
- nice的取值范圍為-20到19,總共40個(gè)級(jí)別。
4.修改進(jìn)程的優(yōu)先級(jí)
在Linux中修改進(jìn)程的優(yōu)先級(jí)是通過(guò)修改PRI和NI。也就是說(shuō),進(jìn)程的優(yōu)先級(jí)是受到nice值的影響的,但是默認(rèn)情況下nice值為0.
新的優(yōu)先級(jí) = 老的優(yōu)先級(jí) + NI
注意:老的優(yōu)先級(jí)指80(即,一旦要修改進(jìn)程的優(yōu)先級(jí),無(wú)論它之前的優(yōu)先級(jí)為多少都將老的優(yōu)先級(jí)設(shè)置為80!),其中NI是nice值,他的取值范圍為[-20,19],這意味著優(yōu)先級(jí)是有取值范圍的[80 - 20,80 + 19]。
修改進(jìn)程的優(yōu)先級(jí),就是修改nice值。
命令是:
sudo top
- 步驟1:
sudo top
- 步驟2:進(jìn)入top后,輸入r然后輸入進(jìn)程的pid(進(jìn)入該進(jìn)程),輸入要修改的nice值。
注意:調(diào)整進(jìn)程的優(yōu)先級(jí)不代表可以隨意調(diào)整,這種做法是操作系統(tǒng)不允許的,會(huì)導(dǎo)致調(diào)度失衡,因此有一定的取值范圍。
總結(jié)
以上就是今天要講的內(nèi)容,本文介紹了創(chuàng)建進(jìn)程、查看進(jìn)程、進(jìn)程的狀態(tài)以及進(jìn)程的優(yōu)先級(jí)相等關(guān)概念。本文作者目前也是正在學(xué)習(xí)C++相關(guān)的知識(shí),如果文章中的內(nèi)容有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牟糠?#xff0c;歡迎大家在評(píng)論區(qū)指出,也歡迎大家在評(píng)論區(qū)提問(wèn)、交流。
最后,如果本篇文章對(duì)你有所啟發(fā)的話(huà),希望可以多多支持作者,謝謝大家!