日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux wait 子孙进程,Linux-进程基础

發布時間:2025/3/15 linux 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux wait 子孙进程,Linux-进程基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

知識點比較雜,需要注意邏輯聯系

1、程序與進程的區別

程序是靜態的,存放在磁盤上,是指令的集合。

進程是程序運行的實例,一個程序運行產生一次產生一個進程。

關于進程,每個進程都有自己的pid,都有自己的PCB,PCB(進程控制塊)記錄了進程使用到的資源。

進程是資源分配的基本的單位,但是不是執行的基本單位。

在Linux操作系統下,進程之間的關系是父子關系或者兄弟關系,所有的用戶級的進程形成了一棵樹??梢允褂胮stree查看。

pstree命令以樹狀圖顯示進程間的關系(display a tree of processes)。ps命令可以顯示當前正在運行的那些進程的信息,但是對于它們之間的關系卻顯示得不夠清晰。在Linux系統中,系統調用fork可以創建子進程,通過子shell也可以創建子進程,Linux系統中進程之間的關系天生就是一棵樹,樹的根就是進程PID為1的init進程。

常用參數

格式:pstree

以樹狀圖顯示進程,只顯示進程的名字,且相同進程合并顯示。

格式:pstree -p

以樹狀圖顯示進程,還顯示進程PID。

格式:pstree

格式:pstree -p

以樹狀圖顯示進程PID為的進程以及子孫進程,如果有-p參數則同時顯示每個進程的PID。

格式:pstree -a

以樹狀圖顯示進程,相同名稱的進程不合并顯示,并且會顯示命令行參數,如果有-p參數則同時顯示每個進程的PID。

因為pstree輸出的信息可能比較多,所以最好與more/less配合使用。

init是這棵樹的樹根,也是1好進程。是用戶進程的第一個進程。環用戶自定義變量不能被子進程繼承,環境變量可以被子進程繼承。

2、創建新進程

使用fork(2)創建新進程

#include

pid_t fork(void);

功能:

參數:

返回值:

失敗:在父進程-1被返回,子進程不被創建,errno被設置

成功:在父進程里返回子進程的PID,子進程得到0的返回值

注意:這里不是一個函數返回兩個值,而是已經存在了兩個進程,是兩個fork的返回值

可以使用ps -aux命令查看進程信息

使用pstree查看進程樹,Linux下的三個特殊進程:idle進程(PID=0),init進程(PID=1),和kthreadd(PID=2)

idle進程由系統自動創建,運行在內核態

idle進程其pid=0,其前身是系統創建的第一個進程,也是唯一一個沒有通過fork或者kernel_thread產生的進程。完成加載系統后,演變為進程調度、交換。

kthreadd進程由idle通過kernel_thread創建,并始終運行在內核空間,負責所有內核進程的調度和管理。

它的任務就是管理和調度其他內核線程kernel_thread, 會循環執行一個kthread的函數,該函數的作用就是運行kthread_create_list全局鏈表中維護的kthread, 當我們調用kernel_thread創建的內核線程會被加入到此鏈表中,因此所有的內核線程都是直接或者間接的以kthreadd為父進程 。

init進程由idle通過kernel_thread創建,在內核空間完成初始化后,加載init程序

在這里我們就主要講解下init進程,init進程由0進程創建,完成系統的初始化,是系統中所有其他用戶進程的祖先進程

Linux中的所有進程都是由init進程創建并運行的。首先Linux內核啟動,然后在用戶空間中啟動init進程,再啟動其他系統進程。在系統啟動完成后,init將變成為守護進程監視系統其他進程。

所以說init進程是Linux系統操作中不可缺少的程序之一,如果內核找不到init進程就會試著運行/bin/sh,如果運行失敗,系統的啟動也會失敗。

3、終止進程

exit(3)和return的區別,return是函數的返回(可以使用echo $?查看最近一次返回結果),exit是進程的結束

exit(3)

#include

void exit(int status)

功能:

終止一個正常進程,status&0377的值返回給父進程

參數:

status:狀態碼

返回值:

不返回

進程退出之前,需要調用一些處理函數進行資源清理,這些函數需要進行注冊

atexit(3)

atexit函數是一個特殊的函數,它是在正常程序退出時調用的函數,我們把他叫為登記函數

#include

int atexit(void (*func)(void))

功能

C 庫函數?int atexit(void (*func)(void))?當程序正常終止時,調用指定的函數?func。您可以在任何地方注冊你的終止函數,但它會在程序終止的時候被調用。

參數

func?- 在程序終止時被調用的函數。

返回值

如果函數成功注冊,則該函數返回零,否則返回一個非零值。

實例

下面的實例演示了 atexit() 函數的用法。

#include

#include

void functionA ()

{

printf("這是函數A\n");

}

int main ()

{

/* 注冊終止函數 */

atexit(functionA );

printf("啟動主程序...\n");

printf("退出主程序...\n");

return(0);

}

在一個程序中最多可以用atexit()注冊32個處理函數,這些處理函數的調用順序與其注冊的順序相反,也即最先注冊的最后調用,最后注冊的最先調用。

執行結果:

執行

before exit()!

on_exit(3)

相關函數 _exit,atexit,exit

函數原型

#include

int on_exit(void (* function)(int,void*),void *arg);

返回值 如果執行成功則返回0,否則返回-1,失敗原因存于errno中。

函數說明 on_exit()用來設置一個程序正常結束前調用的函數。當程序通過調用exit()

或從main中返回時,參數function所指定的函數會先被調用,然后才真正由exit()結束

程序。參數arg指針會傳給參數function函數,詳細情況請見范例。

#include

void my_exit(int status,void *arg)

{

printf(“before exit()!\n”);

printf(“exit (%d)\n”,status);

printf(“arg = %s\n”,(char*)arg);

}

main()

{

char * str=”test”;

on_exit(my_exit,(void *)str);

exit(1234);

}

執行結果:

執行 before exit()!

exit (1234)

arg = test

4、子進程回收

進程結束后,父進程會回收子進程資源,wait(2)、waitpid(2)系統調用可以回收子進程資源。

如果父進程先于子進程結束,那么子進程的父進程將變為init進程。

wait(2)

#include

#include

功能:

這些系統調用用于獲取子進程狀態變化和狀態信息。狀態的變化可以認為是:(1)子進程終止;(2)子進程被信號中止;子進程被信號喚醒。

參數:

參數status如果不是一個空指針,則終止進程的終止狀態就存放在statloc所指向的單元。

參數status如果是一個空指針,則表示父進程不關心子進程的終止狀態

子進程的的退出狀態存放在這塊地址中,可以使用宏檢測退出原因。

WIFEXITED(status):如果子進程正常結束則為非0 值.

WEXITSTATUS(status):取得子進程exit()返回的結束代碼, 一般會先用WIFEXITED 來判斷是否正常結束才能使用此宏.

WIFSIGNALED(status):如果子進程是因為信號而結束則此宏值為真

WTERMSIG(status):取得子進程因信號而中止的信號代碼, 一般會先用WIFSIGNALED 來判斷后才使用此宏.

WIFSTOPPED(status):如果子進程處于暫停執行情況則此宏值為真. 一般只有使用WUNTRACED時才會有此情況.

WSTOPSIG(status):取得引發子進程暫停的信號代碼, 一般會先用WIFSTOPPED 來判斷后才使用此宏.

kill命令用于刪除執行中的程序或工作。

kill可將指定的信息送至程序。預設的信息為SIGTERM(15),可將指定程序終止。若仍無法終止該程序,可使用SIGKILL(9)信息嘗試強制刪除程序。程序或工作的編號可利用ps指令或jobs指令查看。

返回值:

是一個阻塞函數,如果沒有可以回收的子進程,則為阻塞狀態

如果無子進程,則返回-1

如果回收成功,則返回子進程的pid

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 /***********************************************************

9

10

11

12 ***********************************************************/

13 void waitprocess();

14

15

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

17 {

18 waitprocess();

19

20 }

21

22 void waitprocess()

23 {

24

25 int count = 0;

26

27 pid_t pid = fork();

28 int status = -1;

29

30 if(pid<0)

31 {

32 printf("fork error for %m\n",errno );

33 }else if(pid>0)

34 {

35 printf("this is parent ,pid = %d\n",getpid() );

36 wait(&status);//父進程執行到此,馬上阻塞自己,直到有子進程結束。當發現有子進程結束時,就會回收它的資源。

37

38 }else

39 {

40 printf("this is child , pid = %d , ppid = %d\n",getpid(),getppid() );

41 int i;

42

43 for (i = 0; i < 10; i++) {

44 count++;

45 sleep(1);

46

47 printf("count = %d\n", count) ;

48

49 }

50

51 exit(5);

52

53 }

54 printf("child exit status is %d\n", WEXITSTATUS(status));//status是按位存儲的狀態信息,需要調用相應的宏來還原一下

55

56 printf("end of program from pid = %d\n",getpid() );

57

58

59 }

執行結果

通常利用如下代碼來判斷進程的終止原因,和終止信號來源。

wait(&status);

...

//檢測進程是否被信號終止

if(WIFSIGNALED(status)){

//輸出終止子進程的信號編號

printf("signum:%d\n",WTERMSIG(s));

}

在命令行使用kill命令終止相關進程,上述代碼即可輸出終止進程的相關信息。

子進程終止,但是父進程并未回收子進程的相關資源,這時候子進程處于僵尸狀態,成為僵尸進程

waitpid(2)

pid_t waitpid(pid_t pid, int *status, int options);

功能:

等待進程狀態改變。waitpid可以等待任意子進程或者一組子進程的終止;可以設置成阻塞狀態,也可以設置成非阻塞狀態。

參數:

pid:

pid>0只等待進程ID等于pid的子進程,不管其它已經有多少子進程運行結束退出了,只要指定的子進程還沒有結束,waitpid就會一直等下去。

pid=-1等待任何一個子進程退出,沒有任何限制,此時waitpid和wait的作用一模一樣。

pid=0時等待同一個進程組中的任何子進程,如果子進程已經加入了別的進程組,waitpid不會對它做任何理睬。

pid

status:

參數status如果不是一個空指針,則終止進程的終止狀態就存放在status所指向的單元。

參數status如果是一個空指針,則表示父進程不關心子進程的終止狀態

option:

WNOHANG若由pid指定的子進程未發生狀態改變(沒有結束),則waitpid()不阻塞,立即返回0

WUNTRACED返回終止子進程信息和因信號停止的子進程信息

WCONTINUED返回收到SIGCONT信號而恢復執行的已停止子進程狀態信息

0:阻塞

返回值:

成功成功結束運行的子進程的進程號

失敗返回-1

WNOHANG被設置時 沒有子進程退出返回0

wait(&status)等價于waitpid(-1,&status,0)

疑問:如果被設置為非阻塞,父進程先于子進程結束,子進程變為孤進程?由init調用wait回收?

筆記參考: https://www.cnblogs.com/king-77024128/articles/2684317.html

https://www.cnblogs.com/leijiangtao/p/4483009.html

標簽:status,基礎,void,pid,exit,Linux,進程,include

來源: https://www.cnblogs.com/ptfe/p/10972475.html

總結

以上是生活随笔為你收集整理的linux wait 子孙进程,Linux-进程基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。