Linux进程概念(六):进程控制(重要)

目录

进程的创建和终止

进程终止的三种情况

main函数的return 

默认退出码

perror、sterror、errno的区别

自定义退出码

exit函数

_exit函数

exit和_exit的区别

​编辑

进程等待

wait函数

关于status指针和子进程退出信息存在形式的解释

waitpid函数

阻塞等待与非阻塞等待


进程的创建和终止

        进程创建时,操作系统先为进程创建内核数据结构task_struct、mm_struct、页表等,然后再从磁盘中将进程的代码和数据加载进内存中

        进程终止时,先释放曾经的代码和数据所占据的空间,后释放内核数据结构,并将进程修改为僵尸状态Z

进程终止的三种情况

main函数的return 

基本概念:main函数有返回值,是因为父进程想要知道子进程运行的结果,为0表示成功,不为0表示各种原因的失败

默认退出码

基本概念:sterror函数可以打印每个数字对应的错误信息(系统默认提供的)

perror、sterror、errno的区别

自定义退出码

基本概念:使用枚举类型可以自定义退出码,将一个完全大写的变量与某个数字进行绑定

补充内容:代码执行时,出现异常导致提前退出的根本原因是因为该进程收到了OS发给它的信号,可以使用kill - l指令查看所有信号及其编号,并找到相应的信号名称,从而确定进程的退出原因

注意事项:退出码和退出信号互斥,一个进程的退出信息中只可能有其中一个!!!

exit函数

函数原型:void exit(int status);

  • status:进程的终止原因,父进程通过wait获取,为0表示进程正常退出,为1表示异常退出

包含头文件:<stdlib.h>

功能:遇到exit进程直接终止,并将退出码存放在status中

int test3()
{
  int sum = 0;
  for(int i = 0; i < 50; ++i)
  {
    sum += i;
  }
  
  exit(99);
​
  return sum;
}
​
int main()
{
  int ret =  test3();
​
  exit(ret);
  
  return 0;
}

[yyf@hecs-165234 linux101]$ ./myproc 
[yyf@hecs-165234 linux101]$ echo $?
99

_exit函数

函数原型:void _exit(int status);

包含头文件:<unistd.h>

功能:立即终止当前进程,而不进行常规的清理工作(如刷新文件缓冲区、关闭文件流等)

注意事项:_exit和_Exit函数本质上是同一个函数

NAME
       _exit, _Exit - terminate the calling process
​
SYNOPSIS
       #include <unistd.h>
​
       void _exit(int status);
​
       #include <stdlib.h>
​
       void _Exit(int status);

exit和_exit的区别

进程等待

基本概念:进程退出时,必须要将退出信息交给它的父进程,正常情况下父进程也会一直等待接收子进程的退出信息,通过接收子进程的退出信息,可以获取子进程的退出原因并作出相应处理,如果父进程不接收子进程的退出信息(此时子进程的状态为Z),也直接退出,则子进程一直处于僵尸状态,处于僵尸状态的子进程过多会导致系统无法创建新的进程

wait函数

基本概念:wait() 函数是 Unix/Linux 系统中用于等待子进程结束的系统调用。父进程调用 wait() 后,会阻塞,直到它的某个子进程终止,wait() 随后会回收该子进程的系统资源(如进程表项),并返回终止的子进程的退出状态。使用 wait() 可以防止产生僵尸进程,确保父进程获取到子进程的退出状态并清理其资源

函数原型:pid_t wait(int *status);

  • status:输出型数,由OS填充,用于存储子进程的退出信息(退出码或者退出信号),通过宏函数(如 WIFEXITEDWEXITSTATUS可以分析退出状态,判断子进程是正常退出还是被信号终止
 pid_t child_pid = wait(&status);  // 等待子进程结束

if (WIFEXITED(status)) 
{
    printf("父进程:子进程 %d 正常退出,退出码:%d\n", child_pid, WEXITSTATUS(status));
} 
else if (WIFSIGNALED(status)) 
{
    printf("父进程:子进程 %d 因信号终止,信号编号:%d\n", child_pid, WTERMSIG(status));
}
  • 若不关心子进程的退出原因,可以将status设为NULL

返回值:等待成功时返回子进程的pid,等待失败时返回-1

等待失败的原因:

  1. wait() 正在阻塞等待子进程结束,此时进程接收到一个信号(如 Ctrl+C 产生的 SIGINT),导致 wait() 调用中断
  2. 没有子进程可等待
  3. 等待的进程的父进程提前退出,该进程变为孤儿进程

包含头文件:<sys/types.h> 和 <sys/wait.h>

注意事项:父进程一旦调用wait,就会被阻塞,只要有一个子进程结束,就会去接收该子进程的退出信息并将状态转为就绪态

关于status指针和子进程退出信息存在形式的解释

基本概念:wait函数和waitpid函数中的整形指针status指向的存放子进程退出信息的一个整形变量,但是该变量的钱两个字节不会被使用(官方规定)在后两个字节中,前八位表示退出码,后七位表示退出信号,中间一位用于标识coredump(后续会解释)

打印退出信息、退出码和退出信号: 

  • 进程未受到信号干扰,顺利执行完时的退出码不为0,退出信号为0 

打印因信号终止时的退出码和退出信号:

  • 因信号导致进程终止时,退出码为0,退出信号不为0

waitpid函数

基本概念:wait() 函数的一个更强大的变种,它允许父进程精确控制等待的子进程,并且可以选择阻塞或非阻塞的方式等待子进程终止

包含头文件:<sys/types.h> 和 <sys/wait.h>

函数原型:pid_t waitpid(pid_t pid,int *status,int options);

pid:为-1则表示等待任意一个子进程,不为-1则表示等待一个指定子进程

 status:输出型参数,用于存放子进程的退出信息

options:控制 waitpid() 的行为

  • 0:默认行为,阻塞等待直到指定子进程退出。
  • WNOHANG:非阻塞模式,如果没有子进程退出,立即返回,父进程继续执行自己的内容
  • WUNTRACED:如果子进程已停止但尚未终止,也立即返回其状态

返回值:

  • 如果成功等到了一个子进程结束,则返回该子进程PID
  • 如果在options中指定了WNOHANG选项,且没有任何一个子进程已经终止,则返回0
  • 如果出错(例如,指定了无效的 PID 或者调用过程被信号中断),则返回 -1

阻塞等待与非阻塞等待

阻塞等待:父进程在等待子进程返回时什么都不做(稳定可靠)

非阻塞等待:父进程在等待子进程返回时可以去做一些事情(while循环实现)并且在做事情的间隙频繁访问子进程是否返回

非阻塞轮询 = 非阻塞等待 + 循环

父进程会利用回调函数在阻塞轮询的时候执行自己的事情​​​​​​

~over~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值