wordpress在線音樂(lè)/seo狂人
目錄
一、基本概念
二、描述進(jìn)程-PCB
1、task_struct-PCB的一種
2、task_ struct內(nèi)容分類
三、組織進(jìn)程
四、查看進(jìn)程
1、ps指令
2、top命令?
3、/proc文件系統(tǒng)
4、在/proc文件中查看指定進(jìn)程
5、進(jìn)程的工作目錄?
五、通過(guò)系統(tǒng)調(diào)用獲取進(jìn)程標(biāo)示符
1、getpid()/getppid()?
getpid()
getppid()
2、kill命令
五、通過(guò)系統(tǒng)調(diào)用創(chuàng)建進(jìn)程
1、bash
2、fork()
父子進(jìn)程返回結(jié)果不同?
?fork之后有兩個(gè)不同的執(zhí)行流
fork創(chuàng)建進(jìn)程后,為什么會(huì)有兩個(gè)返回值?
3、總結(jié):
一、基本概念
程序的本質(zhì)是文件,以二進(jìn)制形式存儲(chǔ)在磁盤中。當(dāng)程序文件加載到內(nèi)存時(shí),就形成了一個(gè)進(jìn)程。因此,操作系統(tǒng)幫助我們將程序轉(zhuǎn)換為進(jìn)程,以執(zhí)行特定任務(wù)。簡(jiǎn)單來(lái)說(shuō),每次打開(kāi)一個(gè)程序或應(yīng)用時(shí),都會(huì)生成一個(gè)對(duì)應(yīng)的進(jìn)程。
- 教材概念:程序的一個(gè)執(zhí)行實(shí)例,正在執(zhí)行的程序等
- 內(nèi)核觀點(diǎn):擔(dān)當(dāng)分配系統(tǒng)資源(CPU時(shí)間,內(nèi)存)的實(shí)體。
?進(jìn)程=程序的代碼和數(shù)據(jù)(磁盤)+操作系統(tǒng)維護(hù)的進(jìn)程控制塊(PCB)結(jié)構(gòu)體
進(jìn)程是計(jì)算機(jī)中正在運(yùn)行的程序的實(shí)例,它包括了程序的代碼和數(shù)據(jù)(存儲(chǔ)在磁盤上),以及操作系統(tǒng)維護(hù)的進(jìn)程控制塊(PCB)結(jié)構(gòu)體。
- 代碼指的是程序的指令集合,定義了程序的邏輯和執(zhí)行流程。這些指令存儲(chǔ)在磁盤上的可執(zhí)行文件中。當(dāng)進(jìn)程被加載到內(nèi)存中運(yùn)行時(shí),這些指令被復(fù)制到內(nèi)存中的代碼段中,并由處理器執(zhí)行。代碼段通常包括程序的可執(zhí)行指令、函數(shù)、子程序等。
- 數(shù)據(jù)指的是程序在運(yùn)行過(guò)程中使用的變量、常量、對(duì)象等存儲(chǔ)數(shù)據(jù)。數(shù)據(jù)存儲(chǔ)在進(jìn)程的數(shù)據(jù)段中,也就是進(jìn)程的內(nèi)存空間中的一部分。數(shù)據(jù)段包括全局變量、靜態(tài)變量、堆、棧等。
- 這些代碼和數(shù)據(jù)構(gòu)成了進(jìn)程的執(zhí)行環(huán)境,使得程序能夠在計(jì)算機(jī)上正確運(yùn)行。除了代碼和數(shù)據(jù)外,進(jìn)程還包括了操作系統(tǒng)維護(hù)的進(jìn)程控制塊(PCB)。PCB是用于存儲(chǔ)和管理進(jìn)程的各種信息的數(shù)據(jù)結(jié)構(gòu),如進(jìn)程的狀態(tài)、優(yōu)先級(jí)、寄存器值、內(nèi)存分配情況等。PCB存儲(chǔ)了進(jìn)程的標(biāo)識(shí)、狀態(tài)、優(yōu)先級(jí)、程序計(jì)數(shù)器(PC)值、寄存器內(nèi)容、內(nèi)存分配情況等重要信息,是操作系統(tǒng)用于管理和控制進(jìn)程的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。
二、描述進(jìn)程-PCB
在Windows任務(wù)管理器中,我們可以看到許多正在運(yùn)行和后臺(tái)運(yùn)行的進(jìn)程。操作系統(tǒng)需要對(duì)這些進(jìn)程進(jìn)行管理,這是通過(guò)一種稱為進(jìn)程控制塊(PCB)的數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)的。PCB包含了進(jìn)程的屬性信息,類似于文件的內(nèi)容和屬性。
- 進(jìn)程信息被放在一個(gè)叫做進(jìn)程控制塊的數(shù)據(jù)結(jié)構(gòu)中,可以理解為進(jìn)程屬性的集合。
- 課本上稱之為PCB(process control block),Linux操作系統(tǒng)下的PCB是: task_struct
1、task_struct-PCB的一種
- task_struct是Linux內(nèi)核的一種數(shù)據(jù)結(jié)構(gòu),它會(huì)被裝載到RAM(內(nèi)存)里并且包含著進(jìn)程的信息
2、task_ struct內(nèi)容分類
- 標(biāo)示符: 描述本進(jìn)程的唯一標(biāo)示符,用來(lái)區(qū)別其他進(jìn)程。
- 狀態(tài): 任務(wù)狀態(tài),退出代碼,退出信號(hào)等。
- 優(yōu)先級(jí): 相對(duì)于其他進(jìn)程的優(yōu)先級(jí)。(優(yōu)先級(jí):先后順序,權(quán)限:能與不能)
- 程序計(jì)數(shù)器: 程序中即將被執(zhí)行的下一條指令的地址。
- 內(nèi)存指針: 包括程序代碼和進(jìn)程相關(guān)數(shù)據(jù)的指針,還有和其他進(jìn)程共享的內(nèi)存塊的指針。
- 上下文數(shù)據(jù): 進(jìn)程執(zhí)行時(shí)處理器的寄存器中的數(shù)據(jù)[休學(xué)例子,要加圖CPU,寄存器]。
- I/O狀態(tài)信息: 包括顯示的I/O請(qǐng)求,分配給進(jìn)程的I/O設(shè)備和被進(jìn)程使用的文件列表。
- 記賬信息: 可能包括處理器時(shí)間總和,使用的時(shí)鐘數(shù)總和,時(shí)間限制,記賬號(hào)等。
- 其他信息
三、組織進(jìn)程
- 有些操作系統(tǒng)會(huì)把任務(wù)隊(duì)列稱為任務(wù)數(shù)組。但是Linux實(shí)現(xiàn)時(shí)使用的是隊(duì)列而不是靜態(tài)數(shù)組,所以稱為任務(wù)隊(duì)列.
四、查看進(jìn)程
新創(chuàng)建一個(gè)myproc.c文件,為其編寫(xiě)一個(gè)Makefile文件對(duì)其進(jìn)行編譯,然后運(yùn)行myproc這個(gè)死循環(huán)的可執(zhí)行程序方便持續(xù)查看進(jìn)程。?
1、ps指令
ps
?指令是 Linux 中用于顯示當(dāng)前正在運(yùn)行的進(jìn)程的命令。它提供了有關(guān)進(jìn)程的各種信息,例如進(jìn)程的 PID(進(jìn)程標(biāo)識(shí)符)、CPU 和內(nèi)存使用情況等。
- 默認(rèn)情況下,如果你只輸入?
ps
?命令而不加任何選項(xiàng),它會(huì)顯示與當(dāng)前終端會(huì)話相關(guān)的進(jìn)程信息。這可能包括 Shell 以及你通過(guò)該 Shell 啟動(dòng)的其他進(jìn)程。
ps axj | grep 'myproc'
- 這個(gè)命令是將兩個(gè)命令結(jié)合起來(lái)使用,首先執(zhí)行?
ps axj
?命令,它會(huì)顯示所有進(jìn)程的詳細(xì)信息。然后使用管道?|
?將輸出傳遞給?grep 'myproc'
?命令,grep
?是用于搜索指定模式的文本的工具。- 因此,
ps axj | grep 'myproc'
?命令的作用是從所有進(jìn)程的詳細(xì)信息中過(guò)濾出包含字符串?'myproc'
?的行。這樣就能找到與?'myproc'
?相關(guān)的進(jìn)程信息。a
?選項(xiàng)表示顯示所有用戶的進(jìn)程,而不僅僅是當(dāng)前用戶的進(jìn)程。x
?選項(xiàng)表示顯示沒(méi)有控制終端的進(jìn)程,即顯示所有進(jìn)程而不僅僅是與當(dāng)前終端關(guān)聯(lián)的進(jìn)程。j
?選項(xiàng)表示以作業(yè)控制的格式顯示進(jìn)程信息,這種格式通常包括更多關(guān)于進(jìn)程的詳細(xì)信息。
ps axj | head -1 && ps axj | grep 'myproc'
- 首先執(zhí)行?
ps axj
?命令,它會(huì)顯示所有進(jìn)程的詳細(xì)信息。然后使用管道?|
?將輸出傳遞給?head -1
?命令,head -1
?只會(huì)顯示輸出的第一行,即列標(biāo)題行,這樣可以讓我們看到列的含義。- 接著,
&&
?運(yùn)算符表示如果前一個(gè)命令成功執(zhí)行(即返回狀態(tài)碼為 0),則執(zhí)行下一個(gè)命令。因此,如果第一個(gè)命令成功執(zhí)行,就會(huì)繼續(xù)執(zhí)行第二個(gè)命令。- 第二個(gè)命令是?
ps axj | grep 'myproc'
,它會(huì)從所有進(jìn)程的詳細(xì)信息中過(guò)濾出包含字符串?'myproc'
?的行。這樣就能找到與?'myproc'
?相關(guān)的進(jìn)程信息。
2、top命令?
top
?命令是一個(gè)交互式的實(shí)用程序,用于動(dòng)態(tài)監(jiān)視系統(tǒng)的進(jìn)程活動(dòng)和資源利用情況。它可以顯示各個(gè)進(jìn)程的 CPU 占用、內(nèi)存占用、以及其他系統(tǒng)資源的使用情況。top
?命令提供了一個(gè)實(shí)時(shí)更新的進(jìn)程列表,用戶可以通過(guò)鍵盤命令與其交互,例如排序進(jìn)程、終止進(jìn)程等。下面是一些常用的?
top
?命令的鍵盤快捷鍵:
q
:退出?top
?命令。k
:終止進(jìn)程。輸入該命令后,會(huì)提示輸入需要終止的進(jìn)程的 PID。Space
:更新顯示。1
:切換到顯示每個(gè) CPU 核心的獨(dú)立信息。M
:按內(nèi)存使用量排序。P
:按 CPU 使用量排序。T
:按時(shí)間排序。
top
?命令的輸出通常包括:
- 系統(tǒng)概述:系統(tǒng)的運(yùn)行時(shí)間、平均負(fù)載等。
- 進(jìn)程信息:各個(gè)進(jìn)程的 PID、CPU 使用率、內(nèi)存使用量等。
- 系統(tǒng)資源:CPU 使用率、內(nèi)存使用情況、交換分區(qū)使用情況等。
3、/proc文件系統(tǒng)
進(jìn)程的信息可以通過(guò) /proc 系統(tǒng)文件夾查看,/proc
?是一個(gè)特殊的虛擬文件系統(tǒng),用于在Linux系統(tǒng)中提供進(jìn)程和系統(tǒng)信息。雖然它在文件系統(tǒng)中顯示為一個(gè)目錄,但實(shí)際上它是一個(gè)由內(nèi)核動(dòng)態(tài)生成的虛擬文件系統(tǒng),用于向用戶空間提供系統(tǒng)和進(jìn)程的信息。通過(guò)訪問(wèn)?/proc
?目錄,可以查看和管理運(yùn)行中的進(jìn)程,以及獲取有關(guān)系統(tǒng)狀態(tài)和配置的信息。
ls /proc
- 這個(gè)目錄是動(dòng)態(tài)的,多一個(gè)進(jìn)程就多一個(gè)目錄,少一個(gè)進(jìn)程就少一個(gè)目錄。
ls /proc -l???
4、在/proc文件中查看指定進(jìn)程
查找?myproc
?進(jìn)程:?
ps axj | grep myproc
?使用?
ps axj
?命令列出所有進(jìn)程的詳細(xì)信息,然后用?grep
?過(guò)濾出包含?myproc
?的行。輸出顯示?myproc
?進(jìn)程的 PID 是 24857,同時(shí)也顯示了運(yùn)行?grep
?命令本身的進(jìn)程信息。
在?/proc
?目錄中查找進(jìn)程:?
ls /proc -l | grep '24857'
?這個(gè)命令列出了?
/proc
?目錄的內(nèi)容,并使用?grep
?查找與?myproc
?進(jìn)程 PID(24857)相關(guān)的目錄。/proc
?文件系統(tǒng)包含了系統(tǒng)信息和正在運(yùn)行的每個(gè)進(jìn)程的詳細(xì)信息。每個(gè)進(jìn)程都有一個(gè)以其 PID 命名的目錄。輸出顯示了 PID 為 24857 的進(jìn)程的目錄。
列出?/proc/24857
?目錄的內(nèi)容:?
ls /proc/24857
??通過(guò)列出?
/proc/24857
?目錄的內(nèi)容,可以看到與進(jìn)程相關(guān)的許多文件和目錄。這些文件和目錄提供了關(guān)于進(jìn)程的各種信息,包括:
cmdline
:進(jìn)程啟動(dòng)命令。cwd
:進(jìn)程的當(dāng)前工作目錄。environ
:進(jìn)程的環(huán)境變量。exe
:到啟動(dòng)進(jìn)程的可執(zhí)行文件的符號(hào)鏈接。fd
:包含指向進(jìn)程打開(kāi)的文件描述符的符號(hào)鏈接。status
:進(jìn)程的狀態(tài)信息。mem
:進(jìn)程的內(nèi)存映射。- 等等其他許多提供關(guān)于進(jìn)程運(yùn)行狀態(tài)、資源使用情況等信息的文件和目錄。
5、進(jìn)程的工作目錄?
其中cwd表示當(dāng)前進(jìn)程的工作目錄
以前學(xué)習(xí)的FILE *fp = fopen("log.txt","w"),第一個(gè)參數(shù)沒(méi)有帶路徑,默認(rèn)打開(kāi)當(dāng)前路徑。為什么呢?
這是因?yàn)槲覀兊某绦蚪?jīng)過(guò)編譯形成可執(zhí)行程序,打開(kāi)文件運(yùn)行后,形成一個(gè)進(jìn)程,每個(gè)進(jìn)程都會(huì)有一個(gè)屬性,來(lái)保存自己的工作路徑。
五、通過(guò)系統(tǒng)調(diào)用獲取進(jìn)程標(biāo)示符
1、getpid()/getppid()?
?使用man手冊(cè)查看使用方法?
getpid()
- 功能:
getpid()
?函數(shù)用于獲取當(dāng)前進(jìn)程的進(jìn)程 ID(PID)。 - 返回值:它返回一個(gè)?
pid_t
?類型的值,即當(dāng)前進(jìn)程的 PID。在 Linux 中,每個(gè)運(yùn)行的進(jìn)程都有一個(gè)唯一的進(jìn)程標(biāo)識(shí)符,用于區(qū)分不同的進(jìn)程。 - 使用場(chǎng)景:該函數(shù)在需要根據(jù)進(jìn)程 ID 進(jìn)行進(jìn)程管理或信息記錄時(shí)非常有用。例如,日志記錄時(shí)可能需要記錄發(fā)起日志條目的進(jìn)程 ID。
getppid()
- 功能:
getppid()
?函數(shù)用于獲取當(dāng)前進(jìn)程的父進(jìn)程的進(jìn)程 ID(PPID)。 - 返回值:同樣返回一個(gè)?
pid_t
?類型的值,即當(dāng)前進(jìn)程的父進(jìn)程的 PID。當(dāng)一個(gè)進(jìn)程被創(chuàng)建(通常是通過(guò)?fork()
?調(diào)用)時(shí),創(chuàng)建它的進(jìn)程成為其父進(jìn)程。 - 使用場(chǎng)景:這在需要了解或控制進(jìn)程的層級(jí)結(jié)構(gòu)時(shí)非常有用,比如,在創(chuàng)建守護(hù)進(jìn)程時(shí),可能會(huì)根據(jù)父進(jìn)程的 ID 進(jìn)行特定的邏輯判斷。
下面我們創(chuàng)建一個(gè)myproc.c文件,輸出的pid與我們查詢的進(jìn)程id進(jìn)行比較:?
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{while(1){pid_t id=getpid(); //獲取的是自己的進(jìn)程printf("hello world,pid: &d\n",,id);sleep(1);}return 0;
}
右邊復(fù)制一個(gè)SSH渠道,邊運(yùn)行邊查看,如下圖:
我們可以發(fā)現(xiàn)右邊通過(guò)getpid成功輸出進(jìn)程myproc的pid。?
我們?cè)佥敵鲆幌赂高M(jìn)程id(ppid)?
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{while(1){pid_t id=getpid();printf("hello world, pid: %d, ppid: %d\n",id,getppid());sleep(1);}return 0;
}
輸出結(jié)果 :
2、kill命令
?kill
?命令用于向進(jìn)程發(fā)送信號(hào),以控制進(jìn)程的行為或終止進(jìn)程。它的基本語(yǔ)法是:?
kill [options] <PID>
其中?<PID>
?是要終止的進(jìn)程的進(jìn)程標(biāo)識(shí)符。
常用的?kill
?命令選項(xiàng)包括:
-l
:列出可用的信號(hào)名稱。-9
:發(fā)送強(qiáng)制終止信號(hào),也稱為 SIGKILL,立即終止目標(biāo)進(jìn)程。-15
:發(fā)送終止信號(hào),也稱為 SIGTERM,默認(rèn)行為是終止目標(biāo)進(jìn)程,但它可以被進(jìn)程捕獲、忽略或處理。-SIG<signal>
:使用信號(hào)名稱來(lái)指定要發(fā)送的信號(hào),例如?-SIGTERM
。
例如,要終止PID為22053的進(jìn)程,操作如下:
五、通過(guò)系統(tǒng)調(diào)用創(chuàng)建進(jìn)程
1、bash
每次查詢當(dāng)前運(yùn)行的命令時(shí),我們知道子進(jìn)程是我們創(chuàng)建并運(yùn)行的,那父進(jìn)程是誰(shuí)?
- 父進(jìn)程是bash。
系統(tǒng)中,每個(gè)命令行上運(yùn)行的命令都是由 Bash shell 的一個(gè)子進(jìn)程執(zhí)行。此外,Bash shell 本身也是系統(tǒng)中許多進(jìn)程的父進(jìn)程。 Bash shell 是命令行界面的核心,負(fù)責(zé)解釋和執(zhí)行用戶輸入的命令。
復(fù)習(xí)Shell概念?
- Shell(外殼)是計(jì)算機(jī)操作系統(tǒng)中的一個(gè)用戶界面,用于與操作系統(tǒng)內(nèi)核進(jìn)行交互。Shell允許用戶通過(guò)命令行或圖形用戶界面(GUI)來(lái)執(zhí)行操作系統(tǒng)提供的功能和應(yīng)用程序。Shell接受用戶輸入的命令,并將其解釋并傳遞給操作系統(tǒng)內(nèi)核執(zhí)行。
- 在類Unix操作系統(tǒng)(如Linux、macOS等)中,常見(jiàn)的Shell包括Bash(Bourne Again Shell)、Zsh(Z Shell)、Fish等。這些Shell提供了豐富的命令和功能,使用戶能夠管理文件、運(yùn)行程序、配置系統(tǒng)等操作。
在大多數(shù)Linux系統(tǒng)中,常用的命令行解釋器(shell)是Bash(Bourne Again Shell)。Bash是一個(gè)流行的Unix shell,也是許多Linux發(fā)行版的默認(rèn)shell。它提供了豐富的功能和命令,使用戶能夠與操作系統(tǒng)進(jìn)行交互、執(zhí)行命令、編寫(xiě)腳本等。
如果我們kill -9 bash呢?
kill -9 加上bash的id ,命令行會(huì)會(huì)失效。
-
立即終止會(huì)話:?當(dāng)前終端或會(huì)話中的Bash進(jìn)程會(huì)被立即終止,導(dǎo)致您失去對(duì)該終端會(huì)話的訪問(wèn)。
-
子進(jìn)程可能被終止:?如果該Bash進(jìn)程啟動(dòng)了任何子進(jìn)程,那么這些進(jìn)程可能也會(huì)因?yàn)楦高M(jìn)程的終止而受到影響,除非它們已經(jīng)被設(shè)置為守護(hù)進(jìn)程或與終端會(huì)話分離。
-
未保存的數(shù)據(jù)丟失:?如果您在該Bash會(huì)話中運(yùn)行的程序或編輯器中有未保存的工作,強(qiáng)制終止Bash進(jìn)程將導(dǎo)致這些數(shù)據(jù)丟失。
-
不影響其他Bash會(huì)話:?如果您在同一系統(tǒng)上打開(kāi)了多個(gè)終端會(huì)話,這個(gè)操作只會(huì)影響您向其發(fā)送
kill -9
命令的那個(gè)Bash進(jìn)程。其他Bash會(huì)話及其子進(jìn)程將不受影響。 -
可能需要重新登錄:?終止當(dāng)前會(huì)話的Bash進(jìn)程后,您可能需要重新打開(kāi)一個(gè)新的終端會(huì)話或重新登錄您的用戶賬戶來(lái)恢復(fù)正常操作。
- 注意:每次登入的bash都不同,復(fù)制一個(gè)SSH通道,殺掉bash進(jìn)程,不會(huì)影響另一個(gè)窗口運(yùn)行命令。
2、fork()
在Linux系統(tǒng)中,
fork()
?是一個(gè)系統(tǒng)調(diào)用,用于創(chuàng)建一個(gè)新的進(jìn)程。調(diào)用?fork()
?后,操作系統(tǒng)會(huì)復(fù)制當(dāng)前進(jìn)程的副本,包括代碼段、數(shù)據(jù)段、堆棧等,然后在新的進(jìn)程中運(yùn)行。原始進(jìn)程被稱為父進(jìn)程,新創(chuàng)建的進(jìn)程被稱為子進(jìn)程。
- 在?
fork()
?調(diào)用后,父進(jìn)程和子進(jìn)程會(huì)繼續(xù)執(zhí)行后續(xù)的代碼,但是它們會(huì)有不同的進(jìn)程ID(PID)和返回值。在父進(jìn)程中,fork()
?返回子進(jìn)程的PID,而在子進(jìn)程中,fork()
?返回0。 - 通過(guò)?
fork()
?創(chuàng)建子進(jìn)程后,父子進(jìn)程之間會(huì)共享一些資源,如文件描述符、內(nèi)存映射等,但各自有獨(dú)立的地址空間。這樣可以實(shí)現(xiàn)并發(fā)執(zhí)行,父子進(jìn)程可以在獨(dú)立的執(zhí)行環(huán)境中運(yùn)行不同的任務(wù)。?
按照順序先運(yùn)行沒(méi)有fork的代碼,再運(yùn)行有fork的版本。?
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{printf("I am parent process.\n");printf("you can see me.\n");return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{printf("I am parent process.\n");fork();printf("you can see me.\n");sleep(1);return 0;
}
?輸出結(jié)果如下:我們可以發(fā)現(xiàn)創(chuàng)建子進(jìn)程后有一句被輸出了兩次。
?
這是因?yàn)閯?chuàng)建進(jìn)程后,變?yōu)閮蓚€(gè)程序,一個(gè)是父進(jìn)程,另一個(gè)是子進(jìn)程,他們分別運(yùn)行fork()后面的程序。
父子進(jìn)程返回結(jié)果不同?
我們?cè)儆^察下面代碼的輸出結(jié)果?
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{printf("I am parent process.\n");pid_t ret=fork();printf("ret: %d, pid: %d, ppid: %d\n",ret,getpid(),getppid());sleep(1);return 0;
}
fork為什么給父進(jìn)程返回子進(jìn)程pid,給子進(jìn)程返回0?
- 當(dāng)
fork()
在父進(jìn)程中被調(diào)用時(shí),它會(huì)返回子進(jìn)程的PID(進(jìn)程ID),這樣父進(jìn)程就可以知道新創(chuàng)建的子進(jìn)程的PID,從而可以對(duì)子進(jìn)程進(jìn)行管理或跟蹤。 - 當(dāng)
fork()
在子進(jìn)程中被調(diào)用時(shí),它會(huì)返回0,這樣子進(jìn)程可以通過(guò)返回值來(lái)確定自己是子進(jìn)程,而不是父進(jìn)程。子進(jìn)程可以根據(jù)返回值執(zhí)行自己的邏輯,而不是繼續(xù)執(zhí)行父進(jìn)程的代碼。
?fork之后有兩個(gè)不同的執(zhí)行流
為什么下面else if和else可以同時(shí)輸出呢?因?yàn)閒ork之后有兩個(gè)不同的執(zhí)行流 。
#include <stdio.h>
#include <unistd.h>int main()
{pid_t id=fork();if(id<0){//創(chuàng)建失敗perror("fork");return 1;}else if(id==0){//child processwhile(1){printf("I am child, pid:%d, ppid:%d\n",getpid(),getppid());sleep(1);}}else{//parent processwhile(1){printf("I am father, pid:%d, ppid:%d\n",getpid(),getppid());sleep(1);} }printf("you can see me\n");sleep(1);//進(jìn)程退出順序不一樣return 0;
}
?我們通過(guò)下面命令是用來(lái)監(jiān)視名為"myproc"的進(jìn)程。
while :; do ps axj | head -1 && ps axj | grep myproc | grep -v grep; sleep 1; done
這是一個(gè)無(wú)限循環(huán)(
while :; do ... done
),在循環(huán)內(nèi)部,它首先使用?ps axj | head -1
?命令來(lái)顯示進(jìn)程列表的標(biāo)題行(列名),然后通過(guò)?ps axj | grep myproc | grep -v grep
?命令來(lái)顯示包含 "myproc" 的進(jìn)程,同時(shí)使用?grep -v grep
?來(lái)排除 grep 進(jìn)程本身。最后,sleep 1
?用于每秒暫停一次
我們可以為每次輸出結(jié)果之間加上一條分割線。(###分隔符過(guò)長(zhǎng)僅保留部分)
while :; do ps axj | head -1 && ps axj | grep myproc | grep -v grep; sleep 1; echo "###"; done
fork創(chuàng)建進(jìn)程后,為什么會(huì)有兩個(gè)返回值?
- Linux中的
fork()
系統(tǒng)調(diào)用返回兩次值,這是因?yàn)樵赨nix系統(tǒng)中,fork()
的設(shè)計(jì)是基于父子進(jìn)程的概念。調(diào)用fork()
時(shí),操作系統(tǒng)會(huì)復(fù)制當(dāng)前進(jìn)程,創(chuàng)建一個(gè)新的子進(jìn)程。這個(gè)子進(jìn)程是父進(jìn)程的副本,但它們是兩個(gè)獨(dú)立的進(jìn)程,各自有自己的地址空間。 fork()
創(chuàng)建進(jìn)程后返回兩次值的原因是,在fork()
內(nèi)部,父進(jìn)程和子進(jìn)程各自會(huì)執(zhí)行自己的return語(yǔ)句,這導(dǎo)致了兩次返回。這并不意味著操作系統(tǒng)保存了兩次狀態(tài),而是因?yàn)楦高M(jìn)程和子進(jìn)程在不同的執(zhí)行上下文中各自返回。
3、總結(jié):
- 在操作系統(tǒng)中,當(dāng)需要運(yùn)行一個(gè)進(jìn)程時(shí),實(shí)際上是從任務(wù)結(jié)構(gòu)(
task_struct
)形成的隊(duì)列中選擇一個(gè)任務(wù)結(jié)構(gòu)來(lái)執(zhí)行該進(jìn)程的代碼。進(jìn)程調(diào)度實(shí)質(zhì)上就是在任務(wù)結(jié)構(gòu)隊(duì)列中選擇一個(gè)進(jìn)程的過(guò)程。 - 在創(chuàng)建父子進(jìn)程后,哪個(gè)進(jìn)程先運(yùn)行并不確定。這是由操作系統(tǒng)的調(diào)度器決定的。調(diào)度器會(huì)根據(jù)一定的策略(如優(yōu)先級(jí)、時(shí)間片輪轉(zhuǎn)等)來(lái)決定下一個(gè)要運(yùn)行的進(jìn)程。
- 因此,父子進(jìn)程的執(zhí)行順序不確定,取決于操作系統(tǒng)的調(diào)度算法。