【Linux】进程控制(进程退出和进程等待)

文章目录

  • 一、进程退出
    • 1. 进程退出场景
    • 2. 查看每个退出码所传递的信息
    • 3. 终止进程
  • 二、进程等待
    • 1. wait
    • 2. waitpid
    • 3. status参数
    • 4. options参数

一、进程退出

main函数return0是为什么?

main函数返回的是进程的退出码

  • 输出最近一次进程的退出码
echo $?

【Linux】进程控制(进程退出和进程等待)_第1张图片


1. 进程退出场景

  • 代码运行完毕,结果正确
  • ——————,结果不正确
  • 代码异常终止(程序崩溃)

2. 查看每个退出码所传递的信息

strerror

  1 #include 
  2 #include 
  3 using namespace std;
  4 
  5 
  6 int main()
  7 {
  8   for(int i = 0; i < 10; i++)
  9   {
 10     cout << i << ":" << strerror(i) << endl;                                                                                                        
 11   }
 12   return 0;
 13 }
 14 
~

【Linux】进程控制(进程退出和进程等待)_第2张图片

可以看出最多是133

【Linux】进程控制(进程退出和进程等待)_第3张图片


3. 终止进程

exit,强制退出,参数是退出码

【Linux】进程控制(进程退出和进程等待)_第4张图片


二者效果相似,且会将保存在缓冲区的数据输出,缓冲区刷新

exit(EXIT_SUCCESS);
return 0;

_exit 终止进程,但不刷新缓冲区(以及后续的收尾工作)

【Linux】进程控制(进程退出和进程等待)_第5张图片


总结:进程退出三种方式:mian函数return0;exit;_exit;

进程退出,0S层面做了什么:
系统层面,少了一个进程: free PCB, free, mm_ struct, free 页表和各种映射关系,代码+数据申请的空间也要释放掉


二、进程等待

为什么要让父进程等待呢?

  • 通过获取子进程退出的信息,能够得知子进程执行结果。

  • 可以保证时序问题,子进程先退出。父进程后退出

  • 进程退出的时候会先进入僵尸状态,会造成内存泄漏的问题,需要通过父进程wait, 释放该子进程占用的资源


1. wait

#include
#include
pid_t wait(int*status);
返回值:
 成功返回被等待进程pid,失败返回-1。
参数:
 输出型参数,获取子进程退出状态,不关心则可以设置成为NUL

测试:

  1 #include                                 
  2 #include 
  3 #include 
  4 #include 
  5 #include 
  6 #include 
  7 #include 
  8 
  9 using namespace std;
 10 
 11 
 12 int main()
 13 {
 14   pid_t id = fork();
 15 
 16   if(id == 0)
 17   {
 18     int i = 5;
 19     while(i--)
 20     {
 21       printf("child_ PID : %d\n", getpid());
 22       sleep(1);
 23     }
 24     exit(-1);
 25   }
 26 
 27   sleep(10);
 28   pid_t pid = wait(NULL);
 29   printf("father return :%d\n", pid);                                 
 30 
 31 
 32   return 0;
 33 }

【Linux】进程控制(进程退出和进程等待)_第6张图片


2. waitpid

当正常返回的时候waitpid返回收集到的子进程的进程PID

pid_ t waitpid(pid_t pid, int *status, int options);
waitpid(pid, null, 0);//指定子进程
waitpod(-1, null, 0);//任意子进程

3. status参数

  • wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充
  • 如果传递NULL,表示不关心子进程的退出状态信息。 否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程

status是一个整型 linux下4字节,32bit,只使用低16bit,其他未使用

【Linux】进程控制(进程退出和进程等待)_第7张图片


【Linux】进程控制(进程退出和进程等待)_第8张图片


系统提供了宏:

  • WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)

  • WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)

if( WIFEXITED(status) && ret == pid )
{
    printf("code is :%d.\n",WEXITSTATUS(status));
}
else
{
     printf("wait child failed, return.\n");
}

4. options参数

**阻塞等待:**一直等到子进程退出。

本质是:

  • **阻塞的本质:**其实是进程的PCB被放入了等待队列,并将进程的状态改为S状态
  • **返回的本质:**进程的PCB从等待队列拿到R队列,从而被CPU调度

**非阻塞等待:**需要多次发出请求询问是否结束,轮询访问

pid_t pid = fork();
int status = 0;
int ret = waitpid(pid, &status, WNOHANG);

WNOHANG(which no hang(停住了)): 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。


你可能感兴趣的:(C++,programing,langua,退出码,进程控制,linux)