Linux进程控制

本文详细解析了Linux中的进程创建原理,包括fork函数的执行流程和子进程特性;介绍了进程等待函数wait和waitpid,以及如何获取子进程退出状态;最后讲解了进程替换的exec系列函数,如execve和execle的区别。
摘要由CSDN通过智能技术生成

一、进程创建

(1)

#include <unistd.h>

pid_t fork(void);

父进程这返回子进程的pid号,子进程中返回值为0。

fork执行流程:

用户态调用fork函数 -> 触发80中断,切换到内核态执行系统函数(sys_fork)-> 复制当前进程信息(堆栈寄存器内容等)生成子进程 -> 设置当前进程,子进程的eax寄存器(两个进程设置的eax值不同) -> 当前进程返回(return值为eax中的内容) -> fork执行完毕 -> 操作系统切换进程到子进程 -> 子进程获取到返回值(eax)

子进程创建完成后的状态,执行位置处于sys_fork函数即将return的位置

本质上fork函数确实只调用了一次,只不过系统在fork函数中完成对子进程的相关设置后,给父进程的eax寄存器和子进程的eax寄存器设置的值是不同的,从而导致在两个进程中fork函数返回的值不同。

(2)子进程存在写时拷贝机制,只有在实际修改子进程中值的时候,才会给子进程真正分配空间

(3)_exit方式退出进程,将不会执行用户的清除函数 刷新缓冲区 关闭流等。另外,在主函数中的return num 就相当于调用了 exit(num),而exit(num)在执行完用户定义的清理函数 清空缓冲区关闭流之后还是会调用_exit函数

二、进程等待

wait

我们可以使用wait函数来让父进程等待子进程运行结束

它的函数使用方法如下

pid_t wait(int* status);

它的返回值是一个pid_t类型的数据 如果等待成功会返回这个进程的pid 等待失败则会返回-1

status指针是一个输出型参数,用来返回进程运行的结果:

一般用到这个指针指向的int变量的低十六位:

  1. 高八位表示的是退出状态 即我们的退出码
  2. 低七位表示的是终止信号 如果我们的进程被信号所杀则此处会有终止信号
  3. 第八位表示的是core dump标志,表示子进程是否因为出错生成了核心存储文件。有关于core dump的详细信息见Linux Core Dump - 知乎 (zhihu.com)

waitpid

waitpid和wait函数的作用差不多 都是等待一个子进程结束

它的函数使用方法如下

pid_t waitpid(pid_t pid, int* status, int options);

如果等待成功会返回等待进程的pid 如果等待失败则返回-1

这个函数具有三个参数:

pid_t pid

此项参数需要我们填入一个子进程的pid来指定等待该子进程结束

如果我们想等待任意进程都可以 这里可以填-1

int* status

此项参数需要我们填入一个地址

它是一个输出型参数 当我们填入一个地址后该函数会在该地址处写入子进程的退出状态

如果我们不关心这个退出状态 这里可以填写null

int options

此项参数需要我们填入选项

如果我们想要父进程一直等待子进程结束 则可以填入0 (阻塞等待)

如果我们只想父进程问一次子进程有没有结束 则可以填入WNOHANG (非阻塞等待)

宏方法

linux中提供了两个宏来让我们获取退出码和退出信号

它们分别是

  • WIFEXITED(status):用于查看进程是否是正常退出 本质是检查是否收到信号
  • WEXITSTATUS(status):用于获取进程的退出码

三、进程替换

Linux C中进程替换通过六大exec函数完成,他们的区别仅仅在于执行文件的路径、传递参数的方法与环境变量的设置方法不同,其中只有execve才是真正的系统调用。

例如:

execve

int execve(const char *path, char *const argv[], char *const envp[]);

这个v我们可以将它理解为vector 数组的意思 我们传递的参数要以数组的形式传递

这个e意味着它可以自己配置一个环境变量 我们在自己的函数内部就可以使用我们配置的这个环境变量

例如 我们可以自己设置一个env环境变量 并在我们的程序中使用它:

char* myargv[] = { "mycmd", NULL };
char* env[] = { "val", NULL };
execve("./mycmd", myargv, env);

execle

int execle(const char *path, const char *arg, ..., char *const envp[]);

我们首先看这个函数的名字 相比我们的exec多了一个l 多了一个e

多了的这个e意味着它可以自己配置一个环境变量 我们在自己的函数内部就可以使用我们配置的这个环境变量

它的第一个参数是const char *path 它代表着要执行程序的路径

它的第二个参数是 const char *arg, ... 它代表着可变参数列表 是使用NULL结尾的

它的第三个参数是 *const envp[] 它代表着一个数组 数组里面是我们自己配置的环境变量

例如 我们可以自己设置一个env环境变量 并在我们的程序中使用它

char* envp[] = { "val", NULL };
execle("./mycmd", "mycmd", NULL, envp);

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值