Linux进程控制

一.进程创建

fork函数创建子进程

fork函数用于创建子进程,对于父进程返回子进程的Pid,对于子进程返回0

当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方

创建子进程的过程 :  

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中

        子进程也是一个独立的进程,也会有自己的进程控制块PCB,自己的代码和数据,子进程的数据和代码会先和父进程共享一部分,这些数据会被标识为只读

        当父进程或子进程修改这些数据时候,就会触发写实拷贝

写实拷贝 :  通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本

修改之前,父子进程的页表映射的是同一块代码和数据

修改后,发送写实拷贝

二.进程退出

进程退出一般三种情况

  1. 程序运行完成,结果正确
  2. 程序运行完成,结果不正确
  3. 程序异常出错,比如收到信号

进程常见退出方法

1.main函数返回

函数会将main的返回值当做exit的参数。

2.调用库函数或系统调用

这是一个系统调用,用来退出当前进程

这是C语言库函数,用来退出当前进程

显然,C语言库函数void exit(int status) 是封装了系统调用,exit最后也会调用_exit, 但在调用_exit之前,还做了其他工作:

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

exit会清理C语言中各个缓冲区数据,比如输入输出流的数据,而_exit却不会

3.异常中止

比如Ctrl+c会被解释为SIGINT信号,Ctrl+/会被解释为SIGQUIT信号,SIGSEGV段错误

这里不细说,后面在信号章节详细介绍

进程等待

        在进程概念那一章说过, 如果父进程不回收子进程资源,子进程就会进入僵尸状态,进程的PCB没有被释放,会导致内存泄漏,进程等待是为了得到子进程的执行状态和回收资源

wait系统调用 :  等待任意一个子进程, wstatus是输出型参数,获得子进程的退出码,等待成功返回等待进程的pid,失败返回-1

waitpid系统调用 :  等待指定pid的子进程,如果设置为-1,则与wait等效,最后一个参数代表等待方式,可以选择阻塞等待,非阻塞等待等

选择阻塞等待,父进程就会阻塞在wait函数处,直到等待成功

进程退出码

进程的退出码有自己的格式,前两种退出方式都是第一个,异常退出则是第二个

我们可以根据这个来提取进程的退出状态或者退出信号

或者使用宏

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

三.进程替换

进程替换使得我们可以在当前进程去执行一个新的程序,而不用再创建一个新进程

  • l(list) : 表示参数采用列表
  • v(vector) : 参数用数组
  • p(path) : 有p自动搜索环境变量PATH
  • e(env) : 表示自己维护环境变量

第一个参数是要执行新程序的可执行程序名(带p),可执行程序的路径(不带p)

后面的参数可以看成命令行参数的形式,使用列表传参和使用数组传参最后都要以NULL结尾

envp表示要传给新程序的环境变量

进程替换原理

当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序第一条指令开始执行

进程替换前,进程原本的虚拟内存映射到物理内存

执行进程替换后

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值