知识点比较杂,需要注意逻辑联系

1、程序与进程的区别

程序是静态的,存放在磁盘上,是指令的集合。

进程是程序运行的实例,一个程序运行产生一次产生一个进程。

关于进程,每个进程都有自己的pid,都有自己的PCB,PCB(进程控制块)记录了进程使用到的资源。

进程是资源分配的基本的单位,但是不是执行的基本单位。

在Linux操作系统下,进程之间的关系是父子关系或者兄弟关系,所有的用户级的进程形成了一棵树。可以使用pstree查看。

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-进程基础相关推荐

  1. Linux进程管理:进程和线程基础知识

    <Linux进程管理:进程和线程基础知识> <Linux-进程管理> <C语言进程的内存地址空间分配> <进程和线程模型> <(1)Linux进程 ...

  2. linux 进程及调度基础知识

    引用 Linux进程管理专题 Linux进程管理与调度-之-目录导航 Linux下0号进程的前世(init_task进程)今生(idle进程)----Linux进程的管理与调度(五) 蜗窝科技-进程管 ...

  3. linux进程理解,进程资源 - 进程基础 - [ 理解Linux进程 ] - 手册网

    进程资源 进程文件 在Linux中"一切皆文件",进程的一切运行信息(占用CPU.内存等)都可以在文件系统找到,例如看一下PID为1的进程信息. root@87096bf68cb2 ...

  4. Linux进程及进程管理命令

    Linux进程基础 1进程概念 1.1程序与进程 1.2进程的状态 1.3线程 1.4进程生命周期 1.5虚拟内存 2进程管理工具 2.1pstree 2.2ps 2.3pgrep 2.4kill.p ...

  5. 十天学Linux内核之第二天---进程

    十天学Linux内核之第二天---进程 原文:十天学Linux内核之第二天---进程 都说这个主题不错,连我自己都觉得有点过大了,不过我想我还是得坚持下去,努力在有限的时间里学习到Linux内核的奥秘 ...

  6. Linux内核进程管理基本概念-进程、运行队列、等待队列、进程切换、进程调度

    下面简述一些基本概念,以及对内核代码做最初步的了解: 一 Linux内核进程管理基础 Linux 内核使用 task_struct 数据结构来关联所有与进程有关的数据和结构,Linux 内核所有涉及到 ...

  7. Linux下C语言编程-进程的创建

    Linux下C语言编程-进程的创建 作者:hoyt 1.进程的概念 Linux操作系统是面向多用户的.在同一时间可以有许多用户向操作系统发出各种命令.那么操作系统是怎么实现多用户的环境呢?在现代的操作 ...

  8. kill掉多个进程linux中的sudo,linux下批量kill进程的方法

    --kill某个用户下的所有进程(用户为test) --pkill # pkill -u test --killall # killall -u test --ps # ps -ef | grep t ...

  9. Linux 如何取进程运行时间,linux -- 获取进程执行时间

    获取进程执行时间 一.时间概念 在linux下进行编程时,可能会涉及度量进程的执行时间.linux下进程的时间值分三种: 时钟时间(real time):指进程从开始执行到结束,实际执行的时间. 用户 ...

最新文章

  1. apue.h头文件(UNIX环境高级编程)
  2. linux知识记录20192022
  3. 崇天老师python123测验6_嵩天老师python123测验1: Python基本语法元素 (第1周)
  4. windows 临界区
  5. python训练模型测试模型_python 机器学习中模型评估和调参
  6. 在Linux下编写C++程序,使用gcc编译c++出错
  7. 关于DPM(Deformable Part Model)算法中模型结构的解释
  8. 【月报】Java知音的四月汇总
  9. python的一些解释
  10. rsa加密算法实现_深度理解:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  11. FPGA - 7系列 FPGA内部结构之SelectIO -05- 逻辑资源之OLOGIC
  12. Microsoft新闻推荐数据集
  13. UE4地编大型开放世界~制作烘焙全流程
  14. C语言课设分享:图片加载
  15. LeetCode学习-查找2-合并版
  16. 从计数器逻辑中揭秘神奇的HDL
  17. 端口被占用,简单快捷的解决方法
  18. ppm理解与代码实现
  19. [原创] 如何构建成功的QA团队(How to build a successful QA team)
  20. tryhackme圣诞挑战2021-Advent of Cyber 3-day2-越权漏洞,修改cookie

热门文章

  1. weblogic部署,常见错误解决二——ClassCastException
  2. JAVA可以用来开放游戏吗?
  3. 你最近学到的 飞鸽传书 东西的题目
  4. 共享一个复杂的WZSZF数据结构 jshdwz jhcbgc jx8net
  5. 太想成功了--成功之前,你是否养成了这些习惯?
  6. 千万不要成为这样一个程序员!
  7. TCP-Traceroute 核心代码
  8. 有的人能轻松学会Python编程,不是基础好,而是有了这些刷题网站
  9. 经典面试题(4):use strict 有什么意义和好处?
  10. web入门,这些必须掌握!!!