0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

fork出的進程的父進程是從哪來的

電子設(shè)計 ? 來源:電子設(shè)計 ? 作者:電子設(shè)計 ? 2020-12-24 18:41 ? 次閱讀

一、粉絲提問

fork出的進程的父進程是從哪來的?

粉絲提問,一口君必須滿足

粉絲提問

二、解答

這個問題看上去很簡單,但是要想把進程的父進程相關(guān)的所有知識點搞清楚,還是有點難度的,下面我們稍微拓展下,分幾點來講解這個知識點。

1. 如何查看進程ID

每個linux進程都一定有一個唯一的數(shù)字標(biāo)識符,稱為進程ID(process ID),進程ID總是一非負(fù)整數(shù),它的父進程叫PPID。

查看進程ID命令:

ps -ef

查看進程

也可以使用函數(shù)來獲得進程ID:

#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void); 返回:調(diào)用進程的進程ID
pid_t getppid(void); 返回:調(diào)用進程的父進程ID

2. 第一個進程init

Linux內(nèi)核啟動之后,會創(chuàng)建第一個用戶級進程init,由上圖可知, init 進程 (pid=1) 是除了 idle 進程 (pid=0,也就是 init_task) 之外另一個比較特殊的進程,它是 Linux 內(nèi)核開始建立起進程概念時第一個通過 kernel_thread 產(chǎn)生的進程,其開始在內(nèi)核態(tài)執(zhí)行,然后通過一個系統(tǒng)調(diào)用,開始執(zhí)行用戶空間的 / sbin/init 程序。

3. fork函數(shù)

創(chuàng)建一個進程很簡單,先來認(rèn)識一下fork函數(shù):

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
返回:子進程中為0,父進程中為子進程I D,出錯為-1

由fork創(chuàng)建的新進程被稱為子進程( child process)。該函數(shù)被調(diào)用一次,但返回兩次,兩次返回的區(qū)別是子進程的返回值是0,而父進程的返回值則是子進程的進程ID。

一般來說,在f o r k之后是父進程先執(zhí)行還是子進程先執(zhí)行是不確定的。這取決于內(nèi)核所使用的調(diào)度算法。

「舉例:」

#include <unistd.h>
int main()

pid_t pid;

if ((pid = fork()) == -1) {
perror("fork");
return -1;
} else if (pid == 0) {
this is child process
printf("The return value is %d In child process!! My PID is %d, My PPID is %d", pid,getpid(), getppid());

} else {
this is parent
printf("The return value is %d In parent process?。?My PID is %d, My PPID is %d", pid,getpid(), getppid());

return 0;

執(zhí)行結(jié)果:

fork

由上圖可知,fork被調(diào)用了一次,返回了兩次。

【拓展】

使用fork函數(shù)得到的子進程是父進程的處繼承了整個進程的地址空間,包括:「進程上下文、進程堆棧、內(nèi)存信息、打開的文件描述符、信號控制設(shè)置、進程優(yōu)先級、進程組號、當(dāng)前工作目錄、根目錄、資源限制、控制終端」等。

fork

fork出的子進程會集成父進程的文件描述符,如果讀寫文件,父子進程之間會互相影響。

4. ./run 運行的程序父進程是誰?

我們來編寫一個例子:

int main(int argc, const char *argv[])

while(1);
return 0;

編譯執(zhí)行

gcc test.c
./a.out

例子很簡單,就是創(chuàng)建一個死循環(huán)的進程。

ps -ef 查看進程ID

執(zhí)行結(jié)果

由上圖可知,a.out進程的進程ID是2991,父進程ID是2675,即進程bash:

2665

bash的父進程是gnome-terminal,所以大家應(yīng)該明白,我們打開1個Linux終端,其實就是啟動了1個gnome-terminal進程。我們在這個終端上執(zhí)行./a.out其實就是利用gnome-terminal的子進程bash通過execve()將創(chuàng)建的子進程裝入a.out:

strace

5. 進程和終端的關(guān)系

關(guān)于進程和終端的關(guān)系可以參考以下文章:

《進程組、會話、控制終端概念,如何創(chuàng)建守護進程?》

6. 父進程死了,子進程怎么辦?

1) 僵尸進程

僵尸進程

如上圖所示,

父進程Process A創(chuàng)建子進程Process B,當(dāng)子進程退出時會給父進程發(fā)送信號SIGCHLD;如果父進程沒有調(diào)用wait等待子進程結(jié)束,退出狀態(tài)丟失,轉(zhuǎn)換成僵死狀態(tài),子進程會變成一個僵尸進程。

當(dāng)父進程調(diào)用wait,僵尸子進程的結(jié)束狀態(tài)被提取出來,子進程被刪除,并且wait函數(shù)立刻返回。

實例

#include <sys/types.h>
#include <unistd.h>
create a ZOMBIE
* ps -ax | grep a.out to show the zombie

int main()

if(fork()) {
//父進程
while(1){
sleep(1);


//子進程

上述程序會保證父進程不退出,一直在while(1)中無限循環(huán),而子進程會立刻退出。

僵尸進程

由上圖可知,父進程是3096,子進程是3097,子進程因為退出后父進程沒有調(diào)用wait回收子進程資源,所以子進程3097變成僵尸進程defunct。

ps -ax | grep a.out 查看進程狀態(tài)

僵尸進程

2) 孤兒進程

如果父進程退出,并且沒有調(diào)用wait函數(shù),它的子進程就變成孤兒進程,會被一個特殊進程繼承,這就是init進程,init 進程會自動清理所有它繼承的僵尸進程。

實例代碼:

#include <sys/types.h>
#include <unistd.h>

int main()

if(fork()) {
//父進程

}else{
//子進程
while(1){
sleep(1);


上述程序會保證子進程不退出,一直在while(1)中無限循環(huán),而父進程會立刻退出。

孤兒進程:

孤兒進程

./a.out的父進程ID變成1,所以該子進程被init進程繼承。

三、其他啟動進程的方法

1. exec族函數(shù)

fork函數(shù)用于創(chuàng)建一個子進程,該子進程幾乎拷貝了父進程的全部內(nèi)容。exec函數(shù)族提供了一種在進程中啟動另一個程序執(zhí)行的方法。它可以根據(jù)指定的文件名或目錄名找到可執(zhí)行文件,并用它來取代原調(diào)用進程的數(shù)據(jù)段、代碼段和堆棧段。在執(zhí)行完之后,原調(diào)用進程的內(nèi)容除了進程號外,其他全部都被替換了。可執(zhí)行文件既可以是二進制文件,也可以是任何Linux下可執(zhí)行的腳本文件。

每當(dāng)進程調(diào)用一種exec函數(shù)時,該進程完全由新程序代換,而新程序從main函數(shù)開始執(zhí)行。Exec并不創(chuàng)建新進程,所以前后進程ID也不會變。Exec只是用另一個新程序替換了當(dāng)前進程的正文、數(shù)據(jù)、堆和棧段。

「何時使用?」

當(dāng)進程認(rèn)為自己不能再為系統(tǒng)和用戶做出任何貢獻了時就可以調(diào)用exec函數(shù),讓自己執(zhí)行新的程序如果某個進程想同時執(zhí)行另一個程序,它就可以調(diào)用fork函數(shù)創(chuàng)建子進程,然后在子進程中調(diào)用任何一個exec函數(shù)。這樣看起來就好像通過執(zhí)行應(yīng)用程序而產(chǎn)生了一個新進程一樣。

「函數(shù)原型」

函數(shù)原型

2. cron命令

在Linux系統(tǒng)中,計劃任務(wù)一般是由cron承擔(dān),我們可以把cron設(shè)置為開機時自動啟動。cron啟動后,它會讀取它的所有配置文件(全局性配置文件/etc/crontab,以及每個用戶的計劃任務(wù)配置文件),然后cron會根據(jù)命令和執(zhí)行時間來按時來調(diào)用度工作任務(wù)。

檢查cron是否安裝:

ps -ef | grep cron

croncrontab -u //設(shè)定某個用戶的cron服務(wù),一般root用戶在執(zhí)行這個命令的時候需要此參數(shù)
crontab -l //列出某個用戶cron服務(wù)的詳細(xì)內(nèi)容
crontab -r //刪除某個用戶的cron服務(wù)
crontab -e //編輯某個用戶的cron服務(wù)

root查看自己的cron設(shè)置:

crontab -u root -l

或者直接看自己名下的任務(wù):

crontab -l

創(chuàng)建任務(wù):

crontab -e

打開默認(rèn)編輯器編輯后保存退出即可

編輯基本格式 :

*****command
分 時 日 月 周 命令
第1列表示分鐘1~59 每分鐘用*或者 1表示
第2列表示小時1~23(0表示0點)
第3列表示日期1~31
第4列表示月份1~12
第5列標(biāo)識號星期0~6(0表示星期天)
第6列要運行的命令
如果寫為*, 表示每X
如果想定義間隔,在X后加"/"和間隔的數(shù)字

每隔一分鐘打印一下系統(tǒng)時間

1 * * * * date >> ~/t.log //>> means append

3. at

在linux系統(tǒng)如果你想要讓自己設(shè)計的備份程序可以自動在某個時間點開始在系統(tǒng)底下運行,而不需要手動來啟動它,又該如何處置呢?

這些例行的工作可能又分為一次性定時工作與循環(huán)定時工作,在系統(tǒng)內(nèi)又是哪些服務(wù)在負(fù)責(zé)?

還有,如果你想要每年在老婆的生日前一天就發(fā)出一封信件提醒自己不要忘記,linux系統(tǒng)下該怎么做呢?

但是crontab 主要用來提交不斷循環(huán)執(zhí)行的job, 而at 用來提交一段時間后執(zhí)行的job(執(zhí)行完就自動刪除整個job)

「舉例:」

1) 首先檢查atd服務(wù)有無開啟在一個指定的時間執(zhí)行一個指定任務(wù),只能執(zhí)行一次,且需要開啟atd進程

ps -ef | grep atd查看,
開啟用/etc/init.d/atd start or restart;
開機即啟動則需要運行 chkconfig --level 2345 atd on

2) 定時在11:30am用ls列出當(dāng)前目錄內(nèi)容并寫入~/log文件

cd ~
at 11:30am today
at>ls > ~/t.log
at> <EOT> //按Ctl-D退出

審核編輯:符乾江


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 進程
    +關(guān)注

    關(guān)注

    0

    文章

    201

    瀏覽量

    13938
  • Fork
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    3280
收藏 人收藏

    評論

    相關(guān)推薦

    一文搞懂Linux進程的睡眠和喚醒

    優(yōu)先級、文件描述符(記錄當(dāng)前進程打開的文件)、主要進程標(biāo)識的進程號和進程號: 進程號(PID
    發(fā)表于 11-04 15:15

    鴻蒙開發(fā):【進程模型】

    應(yīng)用中(同一Bundle名稱)的所有UIAbility、ServiceExtensionAbility和DataShareExtensionAbility均是運行在同一個獨立進程(主進程)中,如下圖中綠色部分的“Main Process”。
    的頭像 發(fā)表于 06-13 09:53 ?236次閱讀
    鴻蒙開發(fā):【<b class='flag-5'>進程</b>模型】

    true studio調(diào)試,只顯示匯編進程不顯示C進程的原因?

    true studio 調(diào)試,只顯示匯編進程,不顯示C進程的原因?
    發(fā)表于 04-18 06:56

    淺談Linux的進程

    進程和程序的區(qū)別: 進程是動態(tài)的,程序是靜態(tài)的 一、進程的創(chuàng)建(fork()函數(shù)) int main(){ pid_t pid; pid=fork
    的頭像 發(fā)表于 01-28 15:54 ?234次閱讀
    淺談Linux的<b class='flag-5'>進程</b>

    線程、進程、多線程、多進程和多任務(wù)之間有何關(guān)系?

    進程是程序執(zhí)行時的一個實例,即它是程序已經(jīng)執(zhí)行到課中程度的數(shù)據(jù)結(jié)構(gòu)的匯集。內(nèi)核的觀點看,進程的目的就是擔(dān)當(dāng)分配系統(tǒng)資源(CPU時間、內(nèi)存等)的基本單位。
    的頭像 發(fā)表于 01-11 13:39 ?333次閱讀
    線程、<b class='flag-5'>進程</b>、多線程、多<b class='flag-5'>進程</b>和多任務(wù)之間有何關(guān)系?

    mcu線程和進程的區(qū)別是什么

    MCU線程和進程是嵌入式系統(tǒng)中常見的并行執(zhí)行的概念,它們之間有許多區(qū)別,包括線程與進程的定義、資源管理、通信機制、執(zhí)行方式等等。下面將詳細(xì)介紹MCU線程和進程的區(qū)別。 一、定義與概念 MCU線程
    的頭像 發(fā)表于 01-04 10:45 ?665次閱讀

    Linux中進程、線程和協(xié)程的基礎(chǔ)概念

    進程是計算機中運行的程序的實例,它是操作系統(tǒng)中最基本的執(zhí)行單元之一。每個進程都有自己的獨立內(nèi)存空間、系統(tǒng)資源和代碼執(zhí)行流。這意味著一個進程的崩潰通常不會影響其他進程,
    的頭像 發(fā)表于 12-06 09:22 ?748次閱讀

    linux查看weblogic進程

    在Linux操作系統(tǒng)中,WebLogic是一種常用的Java應(yīng)用服務(wù)器,用于部署和管理企業(yè)級Java應(yīng)用程序。為了確保WebLogic服務(wù)器正常運行,有時我們需要查看WebLogic進程以了解其狀態(tài)
    的頭像 發(fā)表于 12-05 16:07 ?1744次閱讀

    perl進程管理

    1 調(diào)用外部命令 調(diào)用命令的perl程序為該命令的進程,繼承當(dāng)前perl的標(biāo)準(zhǔn)輸入標(biāo)準(zhǔn)輸出
    的頭像 發(fā)表于 12-01 14:23 ?364次閱讀

    如何查看系統(tǒng)是否有僵尸進程

    進程中的指令已經(jīng)執(zhí)行完成,但是進程PCB結(jié)構(gòu)還沒有回收。   即子進程先于進程退出后,子進程
    的頭像 發(fā)表于 11-29 15:52 ?6730次閱讀
    如何查看系統(tǒng)是否有僵尸<b class='flag-5'>進程</b>

    進程由執(zhí)行態(tài)變?yōu)樽枞麘B(tài)的主要原因

    進程在運行過程中,可能由于各種原因而執(zhí)行態(tài)變?yōu)樽枞麘B(tài)。主要原因包括以下幾個方面。 首先,進程可能由于等待外部資源而進入阻塞態(tài)。例如,當(dāng)進程需要從硬盤讀取數(shù)據(jù)時,由于硬盤的讀取速度相對
    的頭像 發(fā)表于 11-17 14:14 ?2756次閱讀

    進程響應(yīng)時間是指什么

    進程響應(yīng)時間是指發(fā)出請求到收到響應(yīng)的時間間隔,是衡量系統(tǒng)性能和用戶體驗的重要指標(biāo)之一。在計算機系統(tǒng)中,進程是指一個正在運行的程序?qū)嵗?。?dāng)用戶發(fā)出請求,系統(tǒng)會創(chuàng)建一個新的進程來處理該請
    的頭像 發(fā)表于 11-17 11:31 ?929次閱讀

    進程寫文件會丟失數(shù)據(jù)嗎

    的 page cache,它是文件系統(tǒng)中用于緩存文件數(shù)據(jù)的緩沖,所以即使進程崩潰了,文件數(shù)據(jù)還是保留在內(nèi)核的 page cache,我們讀數(shù)據(jù)的時候,也是內(nèi)核的 page cache 讀取,因此還是依然讀的進程崩潰前寫入的數(shù)據(jù)
    的頭像 發(fā)表于 11-13 10:57 ?615次閱讀
    <b class='flag-5'>進程</b>寫文件會丟失數(shù)據(jù)嗎

    linux下開發(fā)避免僵尸進程的方法

    進程ID,退出狀態(tài),占用的資源等等),你可能會問,為什么這么麻煩,直接釋放完資源不就行了嗎?這是因為有時它的進程想了解它的退出狀態(tài)。在子進程退出但還未被其父
    的頭像 發(fā)表于 11-11 16:38 ?685次閱讀
    linux下開發(fā)避免僵尸<b class='flag-5'>進程</b>的方法

    進程通信的應(yīng)用場景

    進程的概念 進程是操作系統(tǒng)的概念,每當(dāng)我們執(zhí)行一個程序時,對于操作系統(tǒng)來講就創(chuàng)建了一個進程,在這個過程中,伴隨著資源的分配和釋放??梢哉J(rèn)為進程是一個程序的一次執(zhí)行過程。
    的頭像 發(fā)表于 11-11 14:42 ?564次閱讀
    <b class='flag-5'>進程</b>通信的應(yīng)用場景