一.進(jìn)程
1.進(jìn)程調(diào)度
Linux把所有進(jìn)程通過雙向鏈表的方式連接起來組成任務(wù)隊(duì)列,操作系統(tǒng)和cpu通過選擇一個(gè)task_struct執(zhí)行其代碼來調(diào)度進(jìn)程。
2.進(jìn)程的狀態(tài)
1.運(yùn)行態(tài):pcb結(jié)構(gòu)體在運(yùn)行或在運(yùn)行隊(duì)列中排隊(duì)。
2.阻塞態(tài):等待非cpu資源就緒(硬盤,網(wǎng)卡等資源)
3.掛起態(tài):一個(gè)進(jìn)程對(duì)應(yīng)的代碼和數(shù)據(jù)被操作系統(tǒng)因?yàn)橘Y源不足而導(dǎo)致操作系統(tǒng)將該進(jìn)程的代碼和數(shù)據(jù)臨時(shí)地置換到磁盤當(dāng)中,進(jìn)程的pcb還在內(nèi)存中。
3.linux下進(jìn)程的狀態(tài)
R:對(duì)應(yīng)上面的運(yùn)行態(tài)
S:(可中斷睡眠),對(duì)應(yīng)上面的阻塞狀態(tài)
D:深度睡眠,不可被中斷。深度睡眠的狀態(tài)進(jìn)程,只能通過 “一覺睡到自然醒” 自己醒來,OS 無權(quán)喚醒或殺死之。
T:暫停狀態(tài)(調(diào)試)
X:dead終止,瞬時(shí)性非常強(qiáng)
Z:僵尸狀態(tài)
二.深入理解fork
1.介紹fork
fork通過復(fù)制一份當(dāng)前進(jìn)程(父進(jìn)程)來創(chuàng)建一份全新的進(jìn)程(子進(jìn)程),父進(jìn)程創(chuàng)建成功返回子進(jìn)程的pid,失敗返回-1,子進(jìn)程創(chuàng)建成功返回0,失敗返回-1。
2.為何會(huì)有兩個(gè)返回值?
fork可以分為以上三步:1.操作系統(tǒng)先將用戶態(tài)轉(zhuǎn)為內(nèi)核態(tài)通過系統(tǒng)調(diào)用create創(chuàng)建一個(gè)空進(jìn)程。2.調(diào)用clone將父進(jìn)程的代碼和數(shù)據(jù)(數(shù)據(jù)段,堆棧等)完全拷貝給子進(jìn)程。3.return 返回。
當(dāng)父進(jìn)程通過前兩步創(chuàng)建出子進(jìn)程并把代碼數(shù)據(jù)復(fù)制完成后,父進(jìn)程便return返回子進(jìn)程的pid。子進(jìn)程有了父進(jìn)程的所有數(shù)據(jù)(堆棧信息,pcb),由于pcb中記錄了父進(jìn)程代碼執(zhí)行到的位置,因此子進(jìn)程會(huì)接著執(zhí)行后續(xù)return語句,失敗返回-1,成功返回0.
3.fork底層剖析
三個(gè)調(diào)用的區(qū)別在于傳入的參數(shù)不同
具體細(xì)節(jié)參考
資料1
資料2
資料3
1.fork() 和 vfork() 參數(shù)是寫死的,而 clone() 是可選的,它可以選擇當(dāng)前創(chuàng)建的進(jìn)程哪些部分是共享的,哪些部分是獨(dú)立的;
2. vfork() 是歷史的產(chǎn)物,當(dāng)調(diào)用 fork() 的時(shí)候,需要將父進(jìn)程的線性區(qū)和頁表都拷貝一份,而調(diào)用 exec()執(zhí)行新程序后,又要把所有頁表刪除重置新的頁表,建立映射關(guān)系,效率很低;
3.所以要有 vfork(),vfork() 的 clone_flags 位置了 CLONE_VM ,表示共享父進(jìn)程的地址空間,vfork()中創(chuàng)建的進(jìn)程沒有分配自己的地址空間,而是通過一個(gè) mm_struct 指針指向父進(jìn)程的地址空間,這個(gè)進(jìn)程是為了在之后調(diào)用 exec() 執(zhí)行新的程序; 而在有了 Copy-on-write 技術(shù)后,fork()出的子進(jìn)程只創(chuàng)建了自己的地址空間,然后用父進(jìn)程的地址空間初始化,每個(gè)頁表的項(xiàng)置為父進(jìn)程的頁表項(xiàng),共享父進(jìn)程的物理頁面,并將所有 私有/可寫頁面改為只讀;
4.當(dāng)我們改變父子進(jìn)程的數(shù)據(jù)后,cpu 在運(yùn)行過程中會(huì)發(fā)生一個(gè)缺頁錯(cuò)誤,cpu 轉(zhuǎn)交控制權(quán)給操作系統(tǒng),操作系統(tǒng)查找 VMA。發(fā)現(xiàn)該頁權(quán)限為只讀,但所在段又是可寫的,產(chǎn)生一個(gè)矛盾,這就是識(shí)別 Copy-on-write 的方法,接著 OS給子進(jìn)程分配一個(gè)新的物理頁,并將頁表該頁的地址修改成新的物理頁地址;這樣 fork() 后再調(diào)用 exec() 就不用那么麻煩了,可以直接將新的物理頁與子進(jìn)程的虛擬空間建立映射。
三.linux中的pcb實(shí)體task_struct
參考資料4
四.進(jìn)程優(yōu)先級(jí)
1.優(yōu)先級(jí)
優(yōu)先級(jí)PRI=nice+old(pri),PRI越小,優(yōu)先級(jí)越高。
linux下調(diào)整優(yōu)先級(jí)就是調(diào)整nice值,nice值從-20到19。
2.并發(fā)和并行
并行:多個(gè)進(jìn)程在多個(gè)cpu下分別同時(shí)運(yùn)行。
并發(fā):多個(gè)進(jìn)程采用進(jìn)程切換通過一個(gè)cpu在一段時(shí)間下(時(shí)間片)讓多個(gè)進(jìn)程推進(jìn)。
上下文:cpu內(nèi)存在寄存器,當(dāng)一個(gè)進(jìn)程a在運(yùn)行時(shí),cpu內(nèi)的寄存器里面一定保存的是進(jìn)程a的臨時(shí)數(shù)據(jù),這些數(shù)據(jù)就叫該進(jìn)程的上下文。為了實(shí)現(xiàn)并發(fā),當(dāng)進(jìn)程a暫時(shí)被切換的時(shí)候,進(jìn)程a會(huì)帶走自己的上下文數(shù)據(jù)(保存在pcb中),目的是為了下次切換回來時(shí)能快速恢復(fù)。
五.環(huán)境變量
1.概念
環(huán)境變量(environment variables)一般是指在操作系統(tǒng)中用來指定操作系統(tǒng)運(yùn)行環(huán)境的一些參數(shù)。
如:我們?cè)诰帉慍/C++代碼的時(shí)候,在鏈接的時(shí)候,從來不知道我們的所鏈接的動(dòng)態(tài)靜態(tài)庫在哪里,但是照樣可以鏈接成功,生成可執(zhí)行程序,原因就是有相關(guān)環(huán)境變量幫助編譯器進(jìn)行查找。
環(huán)境變量通常具有某些特殊用途,還有在系統(tǒng)當(dāng)中通常具有全局特性。
2.常見環(huán)境變量
PATH : 指定命令的搜索路徑
HOME : 指定用戶的主工作目錄(即用戶登陸到Linux系統(tǒng)中時(shí),默認(rèn)的目錄)
SHELL : 當(dāng)前Shell,它的值通常是/bin/bash
3.操作
1.查看環(huán)境變量:echo $ PATH
2.顯示所有環(huán)境變量:env
3.清除環(huán)境變量unset
4.設(shè)置一個(gè)新的環(huán)境變量:export
4.獲取環(huán)境變量
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i = 0;
for(; env[i]; i++){
printf("%s\n", env[i]);
}
return 0;
}
#include <stdio.h>
int main(int argc, char *argv[])
{
extern char **environ;
int i = 0;
for(; environ[i]; i++){
printf("%s\n", environ[i]);
}
return 0;
}
libc中定義的全局變量environ指向環(huán)境變量表,environ沒有包含在任何頭文件中,所以在使用時(shí) 要用extern聲明。文章來源:http://www.zghlxwxcb.cn/news/detail-816118.html
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%s\n", getenv("PATH"));
return 0;
}
常用getenv和putenv函數(shù)來訪問特定的環(huán)境變量文章來源地址http://www.zghlxwxcb.cn/news/detail-816118.html
到了這里,關(guān)于2.【Linux】(進(jìn)程的狀態(tài)||深入理解fork||底層剖析||task_struct||進(jìn)程優(yōu)先級(jí)||并行和并發(fā)||詳解環(huán)境變量)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!