当前位置: 首页 > news >正文

【进程控制】

1. 写时拷贝

父进程创建了子进程,子进程的PCB是拷贝的父进程的PCB,内容一致。并且数据段,代码段,子进程是与父进程共享的(此时权限会被设为只读),当子进程要对其进行修改,此时会发生写时拷贝,将子进程要修改的数据,拷贝一份,单独交给子进程(这一部分权限可写,可读)。
在这里插入图片描述
在这里插入图片描述

2. 进程终止

在这里插入图片描述

2.1 从main返回在这里插入图片描述

2.2 调用exit

在这里插入图片描述

2.3 _exit

在这里插入图片描述
在这里插入图片描述

3. 进程等待

waitwaitpid 是 Unix/Linux 系统中用于处理子进程状态变化的系统调用,通常在 C 或 C++ 编程里使用。下面为你详细介绍:

3.1 wait 函数

  • 函数原型
#include <sys/types.h>
#include <sys/wait.h>pid_t wait(int *status);
  • 功能wait 函数会让调用进程阻塞,直到它的任意一个子进程终止。若子进程已经终止,wait 会立即返回。返回值是终止子进程的进程 ID,若出错则返回 -1。
  • 参数status 是一个整型指针,用于存储子进程的终止状态。若不关心终止状态,可将其设为 NULL
  • 示例代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process is running.\n");sleep(2);printf("Child process is exiting.\n");exit(0);} else {// 父进程int status;pid_t child_pid = wait(&status);if (child_pid > 0) {if (WIFEXITED(status)) {printf("Child process %d exited normally with status %d.\n", child_pid, WEXITSTATUS(status));} else if (WIFSIGNALED(status)) {printf("Child process %d was terminated by signal %d.\n", child_pid, WTERMSIG(status));}}}return 0;
}

3.2 waitpid 函数

  • 函数原型
#include <sys/types.h>
#include <sys/wait.h>pid_t waitpid(pid_t pid, int *status, int options);
  • 功能waitpid 函数的功能与 wait 类似,不过它可以指定等待某个特定的子进程,还能通过 options 参数来控制等待行为。返回值是终止子进程的进程 ID,若指定 WNOHANG 且没有子进程终止则返回 0,若出错则返回 -1。
  • 参数
    • pid:用于指定要等待的子进程的进程 ID。若 pid > 0,则等待指定进程 ID 的子进程;若 pid == -1,则等待任意子进程,等同于 wait;若 pid == 0,则等待与调用进程在同一进程组的任意子进程;若 pid < -1,则等待进程组 ID 等于 pid 绝对值的任意子进程。
    • status:和 wait 中的 status 作用相同,用于存储子进程的终止状态。
    • options:是一个位掩码,可使用 WNOHANGwaitpid 非阻塞地返回,即若没有子进程终止则立即返回 0;还可使用 WUNTRACED 来关注因收到信号而停止的子进程。
  • 示例代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process is running.\n");sleep(2);printf("Child process is exiting.\n");exit(0);} else {// 父进程int status;pid_t child_pid = waitpid(pid, &status, WNOHANG);if (child_pid == 0) {printf("No child process has exited yet.\n");} else if (child_pid > 0) {if (WIFEXITED(status)) {printf("Child process %d exited normally with status %d.\n", child_pid, WEXITSTATUS(status));} else if (WIFSIGNALED(status)) {printf("Child process %d was terminated by signal %d.\n", child_pid, WTERMSIG(status));}}}return 0;
}

3.3 区别总结

  • 灵活性wait 只能等待任意子进程终止,而 waitpid 能指定等待某个特定的子进程,并且可以控制等待行为,如非阻塞等待。
  • 阻塞特性wait 是阻塞调用,会一直等待直到有子进程终止;waitpid 可通过 WNOHANG 选项实现非阻塞调用。

4. 进程替换

替换原理
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
在这里插入图片描述
替换函数

4.1 execl

在这里插入图片描述

4.2 execlp

在这里插入图片描述

4.3 execle

在这里插入图片描述

4.4 execv

在这里插入图片描述

4.5 execvp

在这里插入图片描述

4.6 execvpe

execvpe 是 Unix/Linux 系统里 exec 函数族中的一员,该函数族的作用是在当前进程的上下文中执行新程序,替换当前进程的映像。下面详细介绍 execvpe 函数。

4.6.1 函数原型

#include <unistd.h>
#include <stdlib.h>int execvpe(const char *file, char *const argv[], char *const envp[]);

4.6.2 参数说明

  • file:指向要执行的程序文件名的指针。此文件名无需是完整路径,execvpe 会依据 PATH 环境变量来查找该程序。
  • argv:指向参数数组的指针,该数组里的每个元素都是一个指向字符串的指针,代表传递给新程序的参数。数组的第一个元素通常是新程序的名称,最后一个元素必须为 NULL,以此标记参数列表的结束。
  • envp:指向环境变量数组的指针。数组中的每个元素都是形如 name=value 的字符串,用于为新程序设置环境变量。

4.6.3 功能说明

execvpe 函数会用指定的程序替换当前进程的映像。若调用成功,它不会返回;只有在调用失败时,才会返回 -1,并设置相应的错误码。

4.6.4 示例代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {// 定义要执行的程序文件名const char *file = "ls";// 定义传递给程序的参数数组char *argv[] = {"ls","-l",NULL};// 定义环境变量数组char *envp[] = {"PATH=/bin:/usr/bin","HOME=/home/user",NULL};// 调用 execvpe 函数执行新程序int result = execvpe(file, argv, envp);// 如果 execvpe 调用失败,会执行到这里if (result == -1) {perror("execvpe");return 1;}return 0;
}

4.6.5 代码解释

  • 在这个示例中,我们运用 execvpe 函数执行了 ls 程序,并且传递了 -l 参数。
  • 为新程序设置了两个环境变量 PATHHOME
  • execvpe 调用成功,当前进程会被 ls 程序替代,输出文件列表。若调用失败,则会输出错误信息。

4.6.6 注意事项

  • 由于 execvpe 调用成功后不会返回,所以调用之前的代码会被执行,而调用之后的代码只有在调用失败时才会执行。
  • file 参数不是完整路径,execvpe 会依据 envp 数组里的 PATH 环境变量查找程序。若 envp 中未包含 PATH,则使用当前进程的 PATH 环境变量。
  • 传递给新程序的参数列表和环境变量数组都必须以 NULL 结尾。

相关文章:

  • PAT第七题素数对猜想
  • (超级详细)发明专利撰写
  • 码蹄集——输入、输出格式题
  • ACL访问控制列表简单实验CISCO
  • Android 理清 Gradle、AGP、Groovy 和构建文件之间的关系
  • Java高频面试之并发编程-09
  • Gentex EDI 需求分析
  • 投资控股集团类网站建设公司有哪些:打造专业形象与高效沟通的桥梁
  • 【wpf】Treeview控件的另类展示效果
  • Spdlog 日志组件的安装及使用
  • Linux:进程间通信->共享内存
  • 封装el-autocomplete,接口调用
  • 蓝桥杯 11. 打印大X
  • 手搓传染病模型(SEIR)
  • 2025年AEJ SCI2区:增强麻雀搜索算法CERL-SSA+工业物联网感知通信,深度解析+性能实测
  • 视觉导航中的滑动窗口
  • C++ RAII
  • 使用 Autofac 实现依赖注入
  • Redis缓存问题的深度解析与解决方案
  • C语言实现迪杰斯特拉算法进行路径规划
  • 千亿市值光储龙头董事长向母校合肥工业大学捐赠1亿元
  • 幸福航空五一前三天航班取消:客服称目前是锁舱状态,无法确认何时恢复
  • 黄仁勋访华期间表示希望继续与中国合作,贸促会回应
  • 合肥一季度GDP为3003.88亿元,同比增长6.6%
  • 高璞任中国第一汽车集团有限公司党委常委、副总经理
  • 经济日报金观平:统筹国内经济工作和国际经贸斗争