Linux中的进程控制(创建、终止、等待)

进程创建

fork函数

功能:从已存在的进程中创建出一个新的进程。新进程叫子进程,原进程叫父进程。

#include<unistd.h>
  pid_t fork();
返回值:子进程返回0;父进程返回子进程pid;创建失败返回-1

进程调用fork(),当控制转移到内核中的fork代码后,内核会做:

  • 分配新的内存块和内核数据结构给子进程。
  • 将父进程部分数据结构内容拷贝给子进程。
  • 添加子进程到系统进程列表中。
  • fork返回,开始调度调度器。

在这里插入图片描述
当一个进程调用fork后,就有两个二进制代码相同的进程,而且他们都运行到相同的位置,但每个进程都将可以开始他们自己的旅程:
注意

  • fork之前,父进程独立执行,fork之后,父子进程分别执行。
  • fork之后,谁先执行完全由调度器决定。

fork函数返回值

  • 子进程返回0;
  • 父进程返回子进程的pid。

写时拷贝

通常情况下,父子进程代码共享两者都不写入时,数据也是共享的;当任意一方写入时便以写时拷贝的方式,给子进程开辟一个新空间存储被修改的原数据

进程终止

进程退出场景

  • 代码运行完毕,结果正确:
  • 代码运行完毕,结果不正确;
  • 代码异常终止。

进程常见退出方式
正常退出:

  1. 从main(return)退出(退出前刷新缓冲区)
  2. 调用exit(库函数接口,退出前刷新缓冲区,任意地方退出)
  3. _exit(系统调用接口,从任意地方退出,释放所有函数)

异常退出:

  • ctrl+c,信号终止

return退出

return是一种常见的退出进程的方法。执行return n等同于执行exit(n),因为调用了main的运行时,函数会将main的返回值当作exit的参数。

_exit函数

 #include<unistd.h>
 void _exit(int status);
 参数:status定义了进程的终止状态;父进程通过wait来获取该值
  • 说明:虽然status是int,但是只有低8位可以被父进程所用。所以_exit(-1)时,在终端执行$?发现返回值时225。

exit函数

 #include<unistd.h>
 void exit(int status);

exit最后也会调用_exit,但在调用之前,还做了其他工作:

  1. 执行用户通过atexit或on_exit定义的清理函数;
  2. 关闭所有打开的流,所有的缓存数据均被写入:
  3. 调用_exit。

在这里插入图片描述

进程等待

进程等待的必要性

  • 之前了解到,子进程退出时如果父进程不管不顾,就会造成“僵尸进程”的问题,进而造成内存泄漏。
  • 另外,进程一旦变为僵尸进程,就会刀枪不入,连“kill-9”都无能为力,谁都没有办法杀死一个已经死去的进程。
  • 最后,我们需要知道父进程派给子进程的任务完成的如何,如:子进程运行完成,结果对还是不对,或者是否正常退出。
  • 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

进程等待的方法

wait方法

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int *status)//*status是子进程退出的返回值

//返回值:成功返回被等待进程的pid,失败返回-1.
//参数:输出型参数,获取子进程的退出状态,不关心也可以设置成null.

阻塞接口:等待任意一个子进程退出。若没有子进程退出,则一直等待,直到子进程的返回值放入到参数的status中。

waitpid方法

pid_t waitpid(pid_t pid,int *status,int options)
返回值:
-当正常返回时waitpid返回收集到的子进程的进程ID;
-如果设置了选项WNOHANG,而调用中wait发现没有已退出的子进程可以收集,则返回0-如果调用中出错,则返回-1,这是errno会被设置成相应的值以指出错误何在
参数:
pid:
   =1,等待任一个子进程。与wait同效。
   >0,等待其进程ID与pid相等的子进程。
status:
   WIFEXITED(status):若为正常终止子进程返回的状态,则为真。(查看进程是否正常退出)
   WEXITSTATUS(status):若WIFEXITED非零,则提取子进程退出码。(查看进程退出码)
options:
   WNOHANG:若pid的子进程没有结束,则waitpid()函数返回0,不予等待。若正常结束,则返回该子进程的ID。(将waitpid设为非阻塞)
  • 如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程退出信息。
  • 如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞。
  • 如果不存在该子进程,则立即出错返回。

获取子进程status

  • wait和waitpid都有一个status参数,该参数是一个输出型参数,由操作系统填充。
  • 如果传递null,则表示不关心子进程的退出状态
  • 否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。
  • status不能简单地当作整形看待,可以当作位图来看待,如下图:(之研究status的低十六比特位)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值