wordpress用戶名忘記密碼廣州seo站內(nèi)優(yōu)化
什么是進程
什么是程序
一組可以被計算機直接識別的 有序 指令 的集合。
通俗講:C語言編譯后生成的可執(zhí)行文件就是一個程序。
那么程序是靜態(tài)還是動態(tài)的?
程序是可以被存儲在磁盤上的,所以程序是靜態(tài)的。
那什么是進程
進程是程序的執(zhí)行過程,是動態(tài)的,隨著程序的使用被創(chuàng)建,隨著程序的結束而消亡。
可以說進程是一個獨立的可調(diào)度的任務。
進程是系統(tǒng)調(diào)度的獨立任務。
進程是程序執(zhí)行的獨立任務。
進程是資源(內(nèi)存資源)管理的最小任務。
一個程序可以只有一個進程,此時正在運行的這個程序也叫進程。
一個程序也可以有多個進程,此時正在運行的這個程序有多個進程動態(tài)執(zhí)行。
所以說進程可以是程序,但程序不一定是進程。
注意:每一個程序運行時,操作系統(tǒng)分配給進程的 是虛擬內(nèi)存,意味著每一個進程所使用的空間都是虛擬內(nèi)存, 虛擬內(nèi)存會被單元管理模塊(MMU)映射到物理內(nèi)存上,如何映射是操作系統(tǒng)關心的事情,程序開發(fā)者不用關心。
時間片
進程有多個,而CPU只有一個,假設該CPU是單核的,那么在某一時刻CPU只能處理一個進程,但是不能一直去處理這個進程,得多個進程之間輪流處理,給用戶感覺這些進程在同時進行,而CPU處理一個進程的時間段即時間片。時間片是約定好CPU處理一個進程的時間段。
進程的類型
交互進程:完成人機交互的進程,比如shell
批處理進程:比如gcc的四步流程
守護進程:開機自啟動,關機自動關閉(后臺運行)
進程的狀態(tài)
就緒狀態(tài):具備運行條件,等待處理器運行的進程。
當進程已分配到除CPU以外的所有必要資源后,只要再獲得CPU,便可立即執(zhí)行,進程這時的狀態(tài)稱為就緒狀態(tài)。在一個系統(tǒng)中處于就緒狀態(tài)的進程可能有多個,通常將它們排成一個隊列,稱為就緒隊列。
運行狀態(tài):處理器正在運行的進程。
等待狀態(tài):又稱阻塞態(tài)或睡眠態(tài),指進程不具備運行條件,正在等待某個時間完成的狀態(tài)。
也稱為等待或睡眠狀態(tài),一個進程正在等待某一事件發(fā)生(例如請求I/O而等待I/O完成等)而暫時停止運行,這時即使把處理機分配給進程也無法運行,故稱該進程處于阻塞狀態(tài)。
死亡狀態(tài):運行結束的進程。
進程的模式
終端:內(nèi)核發(fā)送的信號。
系統(tǒng)調(diào)用:調(diào)用操作系統(tǒng)提供給用戶來訪問硬件的一組接口。
進程三態(tài)模型
運行態(tài)→等待態(tài):等待使用資源;如等待外設傳輸;等待人工干預。
等待態(tài)→就緒態(tài):資源得到滿足;如外設傳輸結束;人工干預完成。
運行態(tài)→就緒態(tài):運行時間片到;出現(xiàn)有更高優(yōu)先權進程。
就緒態(tài)—→運行態(tài):CPU 空閑時選擇一個就緒進程。
?
孤兒進程
指父進程先于子進程退出,此時子進程稱為孤兒進程。但是該進程會被pid為1的init進程收養(yǎng)。
僵尸進程
指子進程先于父進程退出并且沒有被父進程回收子進程的資源。此時子進程就會變成僵尸進程。僵尸進程會造成浪費空間、資源泄露等問題。
進程的相關系統(tǒng)調(diào)用
?
創(chuàng)建進程
- 每個進程都由父進程創(chuàng)建。
- 通過系統(tǒng)調(diào)用函數(shù) fork() 實現(xiàn)進程創(chuàng)建。
fork()
頭文件:<sys/types.h> <unistd.h>
函數(shù)原型:pid_t fork();
返回值:PID,進程ID號。返回 0 表示子進程,返回-1失敗,返回大于0的整數(shù)表示創(chuàng)建進程的PID。
可以通過getpid()來獲取當前運行的進程ID,通過getppid()獲取當前進程的父進程ID。
?
wait()
頭文件:<sys/wait.h><sys/types.h>
函數(shù)原型:pid_t wait(int* status) status為空時表示忽略子進程退出時的狀態(tài),不為空表示保存子進程退出時的狀態(tài)。
返回值:成功返回子進程的PID,失敗返回-1
使進程進入阻塞狀態(tài)。
直到任意子進程結束或者該進程接收到信號為止。
如果該進程沒有子進程,或子進程已經(jīng)結束。wait()會立即返回。
此函數(shù)時進程阻塞時父進程什么也不干。
該函數(shù)可以獲取子進程終止使的退出狀態(tài)。
?
waitpid()
函數(shù)原型:pid_t waitpid(pid_t pid, int *status, int options)
入?yún)?#xff1a;pid
pid 傳-1時 等待任意子進程與wait功能一樣。
pid 傳0時 等待其組ID等于調(diào)用進程的組ID的任意子進程。
pid 傳 小于-1時 等待其組ID等于PID的絕對值的任意子進程。
入?yún)?#xff1a;status 同wait
status 通過WIFEXITED宏來測驗 子進程正常退出返回true,否則返回false
?
status 通過WEXITSTATUS宏 來查看退出狀態(tài)值。?
?
return exit() _exit() 在WIFEXITED看來都算正常退出
入?yún)?#xff1a;options
傳0 同wait 阻塞父進程
傳WNOHANG:若由PID指定的子進程并不立即可用,則waitpid不會被阻塞,此時返回值為0,子進程結束時返回子進程PID
返回值:正常返回結束的子進程PID,-1失敗,
功能與wait類似。
可以指定等待某個子進程以及等待方式(阻塞或非阻塞)
wait和waitpid都可以實現(xiàn)對子進程資源的回收
exit(int status)
status:退出狀態(tài)。
使進程終止,并清空緩沖區(qū)。
_exit(int status)
使進程終止,但是不會清空緩沖區(qū)。
?Exec函數(shù)族
以exec開頭的一系列函數(shù)
該族函數(shù)提供了在一個進程中執(zhí)行新的進程
通過fork開啟的子進程中擁有與父進程相同的代碼,但是開辟了新的空間,這么做實際意義不大。所以exec族函數(shù)可以對fork創(chuàng)建的子進程進行代碼替換,只保留PID不變,這就實現(xiàn)了在一個進程中產(chǎn)生了新的進程。
?
參數(shù) | 意義 |
---|---|
l(list) | 參數(shù)地址列表,以空指針結尾 |
v(vector) | 存有各參數(shù)地址的指針數(shù)組的地址 |
p(path) | 按 PATH 環(huán)境變量指定的目錄搜索可執(zhí)行文件 |
e(environment) | 存有環(huán)境變量字符串地址的指針數(shù)組的地址 |
守護進程
- 運行在后臺的進程,與終端沒有任何關系。
- 開機自啟動,關機自關閉。
前臺進程
和終端有關系的進程
后臺進程
與終端脫離關系。
變成后臺進程的步驟
- 首先變成孤兒進程。
- 讓自己成為新的進程組組長。
- 讓自己成為新的會話組組長。
- 使控制終端tty變成 ‘?’ 才能完全脫離終端。
?
創(chuàng)建守護進程的步驟
-
創(chuàng)建子進程父進程退出。(為了讓子進程先被init收養(yǎng))
-
創(chuàng)建新的會話組。(通過setsid()函數(shù))讓自己成為新的會話組組長。
?此時守護進程已經(jīng)創(chuàng)建,但是還需要優(yōu)化。再使用chdir()函數(shù)修改守護進程的工作路徑。
重設文件掩碼。將文件掩碼設置為0可以增加守護進程的靈活性?
關閉父進程繼承過來的文件描述符。因為守護進程用不到這些資源,會造成資源浪費。?
?
-
getdtablesize()返回一個進程可以打開的最大文件數(shù)
-
再到/etc/rc.local 文件中exit 0之前 將這個守護進程的絕對路徑寫在這里。開機自啟動。
?