学习笔记——进程控制函数

进程控制函数整理笔记

一、 进程回收函数

wait() - 阻塞回收

#include <sys/wait.h> pid_t wait(int *status);

功能:阻塞等待任意子进程退出并回收状态(只能父进程回收子进程)

参数

  • status:进程退出时的状态

    • 不关心退出状态:NULL

    • 需要回收状态:传变量地址

返回值

  • 成功:回收的子进程PID

  • 失败:-1

状态宏使用

int status; pid_t pid = wait(&status); if (WIFEXITED(status)) { // 是否正常结束 int exit_code = WEXITSTATUS(status); // 获取退出码 printf("子进程正常退出,退出码: %d\n", exit_code); } else if (WIFSIGNALED(status)) { // 是否被信号终止 int sig_num = WTERMSIG(status); // 获取信号编号 printf("子进程被信号终止,信号: %d\n", sig_num); }

waitpid() - 精确控制回收

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

参数

  1. pid

    • >0:指定回收特定PID的子进程

    • -1:回收任意子进程(等价于wait()

    • 0:回收同进程组的子进程

    • <-1:回收指定进程组ID的绝对值

  2. status:同wait()

  3. options

    • 0:阻塞模式(默认)

    • WNOHANG:非阻塞模式

返回值

  • 成功:回收的子进程PID

  • 0WNOHANG模式下,子进程未退出

  • -1:错误

二、 非阻塞回收示例

方式1:循环检查

// 非阻塞回收所有子进程 int status; pid_t pid; while (1) { pid = waitpid(-1, &status, WNOHANG); if (pid > 0) { // 成功回收一个子进程 printf("回收子进程 %d\n", pid); if (WIFEXITED(status)) { printf("退出码: %d\n", WEXITSTATUS(status)); } } else if (pid == 0) { // 没有子进程退出,可以做其他事情 printf("没有子进程退出,继续工作...\n"); sleep(1); } else if (pid == -1) { // 错误或没有子进程了 printf("所有子进程已回收完毕\n"); break; } }

方式2:信号驱动(SIGCHLD)

#include <signal.h> void sigchld_handler(int sig) { int status; pid_t pid; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { printf("子进程 %d 已结束\n", pid); } } int main() { signal(SIGCHLD, sigchld_handler); // ... 创建子进程 }

三、 exec函数族

内存变化

执行exec前:原进程有自己的代码段、数据段、堆栈
执行exec后:原进程的代码段被新程序替换,PID不变,其他资源可能变化

函数对比表

函数路径指定参数传递PATH查找
execl()完整路径参数列表
execlp()文件名参数列表
execv()完整路径参数数组
execvp()文件名参数数组

函数详解

execl() - 参数列表形式
int execl(const char *path, const char *arg, ..., NULL);
  • path:完整路径(如"/usr/bin/ls"

  • arg:参数列表,以NULL结束

execl("/usr/bin/ls", "ls", "-l", "/home", NULL);
execlp() - 自动PATH查找
int execlp(const char *file, const char *arg, ..., NULL);
  • file:程序名,自动在PATH中查找

execlp("ls", "ls", "-l", "/home", NULL);
execv() - 参数数组形式
int execv(const char *path, char *const argv[]);
  • argv:参数数组,最后一项必须是NULL

char *args[] = {"ls", "-l", "/home", NULL}; execv("/usr/bin/ls", args);
execvp() - 自动PATH查找+数组参数
int execvp(const char *file, char *const argv[]);
char *args[] = {"ls", "-l", "/home", NULL}; execvp("ls", args);

调用自己的程序

// 假设当前目录有程序 myapp execl("./myapp", "myapp", "arg1", "arg2", NULL); // 必须带路径 execlp("./myapp", "myapp", "arg1", "arg2", NULL); // 带路径也可 execv("./myapp", args); // 必须带路径 execvp("./myapp", args); // 带路径也可

四、 fork + exec 配合使用

#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid == 0) { // 子进程执行新程序 execlp("ls", "ls", "-l", NULL); // 如果exec失败才会执行到这里 perror("execlp failed"); exit(1); } else if (pid > 0) { // 父进程等待子进程 int status; waitpid(pid, &status, 0); if (WIFEXITED(status)) { printf("子进程退出码: %d\n", WEXITSTATUS(status)); } } return 0; }

五、 system()函数

#include <stdlib.h> int system(const char *command);

功能:执行shell命令(内部实现:fork() + exec()

限制

  • 不能执行需要修改父进程状态的命令(如cd,export等)

  • 适合执行信息输出、文件操作等命令

示例

system("ls -l"); // 列出文件 system("echo hello"); // 输出信息 system("cp file1 file2"); // 复制文件 // ❌ 这些无效(不会影响父进程): system("cd /tmp"); // 只在子shell中切换 system("export VAR=1"); // 只在子shell中设置

六、 工作目录函数

getcwd() - 获取当前工作目录

#include <unistd.h> char *getcwd(char *buf, size_t size);

参数

  • buf:存储路径的字符数组

  • size:数组最大长度

返回值

  • 成功:指向buf的指针

  • 失败:NULL

示例

char cwd[1024]; if (getcwd(cwd, sizeof(cwd)) != NULL) { printf("当前目录: %s\n", cwd); } else { perror("getcwd失败"); }

chdir() - 改变工作目录

int chdir(const char *path);

参数path- 要切换的路径

返回值

  • 成功:0

  • 失败:-1

示例

if (chdir("/tmp") != 0) { perror("chdir失败"); } else { printf("成功切换到 /tmp\n"); }

七、 关键点总结

  1. wait() vs waitpid()

    • wait():简单但只能阻塞回收

    • waitpid():功能更强,支持非阻塞和指定进程

  2. exec函数选择

    • 知道完整路径:用execl()execv()

    • 想用PATH查找:用execlp()execvp()

    • 参数动态:用execv()execvp()

    • 参数固定:用execl()execlp()

  3. 非阻塞回收

    • WNOHANG选项

    • 返回值需要特殊处理

    • 通常放在循环中

  4. cd命令特殊性

    • 必须在当前进程执行chdir()

    • 不能用fork()+exec()实现

    • 不能用system()实现

  5. 僵尸进程避免

    • 及时用wait()waitpid()回收

    • 对于后台进程,可以用信号处理SIGCHLD

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1021895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NIPAP终极指南:免费开源的IP地址管理系统快速上手

NIPAP终极指南&#xff1a;免费开源的IP地址管理系统快速上手 【免费下载链接】NIPAP Neat IP Address Planner - NIPAP is the best open source IPAM in the known universe, challenging classical IP address management (IPAM) systems in many areas. 项目地址: https:…

AutoGPT实战应用:让AI自主完成复杂任务的全流程解析

AutoGPT实战应用&#xff1a;让AI自主完成复杂任务的全流程解析 在信息爆炸的时代&#xff0c;我们每天面对的任务越来越复杂——从撰写一份详尽的市场分析报告&#xff0c;到为孩子制定个性化的学习计划&#xff0c;再到快速生成可运行的代码原型。传统的AI助手虽然能回答问题…

Git下载Stable Diffusion 3.5 FP8源码后如何正确加载FP8权重?

Git下载Stable Diffusion 3.5 FP8源码后如何正确加载FP8权重&#xff1f; 在生成式AI飞速发展的今天&#xff0c;图像生成模型的性能边界不断被刷新。然而&#xff0c;随着模型规模的增长&#xff0c;推理成本、显存占用和部署门槛也急剧上升。面对这一挑战&#xff0c;Stabili…

探索三相光储充变流器的奇妙世界

三相光储充变流器&#xff0c;双路MPPT输入&#xff0c;MPPT工作范围150-1100V,THD值小于3%&#xff0c;功率因数在-0.8-0.8之间&#xff0c;支持50Hz /60Hz&#xff0c;最大并网功率为三相10kw&#xff0c;电网电压范围为300-476VAC&#xff0c;支持锂电池的工作电压范围 90-5…

三菱FX5U与台达DT330温控器通讯及控制实现

三菱FX5U与台达DT330温控器通讯程序输出控制本体远程双设定(SL5U-12) 功能&#xff1a;通过三菱FX5U本体485口&#xff0c;结合触摸屏网口&#xff0c;实现对台达DT330温控器设定温度&#xff0c;读取温度&#xff0c;控制输出启停&#xff0c;以及在温控器本体与远程触摸屏都能…

夸克网盘自动化管理终极指南:从零开始构建智能签到系统

夸克网盘自动化管理终极指南&#xff1a;从零开始构建智能签到系统 【免费下载链接】quark-auto-save 夸克网盘签到、自动转存、命名整理、发推送提醒和刷新媒体库一条龙 项目地址: https://gitcode.com/gh_mirrors/qu/quark-auto-save 想要彻底解放双手&#xff0c;让夸…

19、雾无线接入网络中的未来趋势与开放问题:联邦学习视角

雾无线接入网络中的未来趋势与开放问题:联邦学习视角 在雾无线接入网络(F-RANs)中,利用分散的计算资源生成高质量的学习模型是一项具有挑战性的任务。模型训练过程需要大量的计算,对计算能力有很高的要求。尽管F-RANs边缘存在许多雾计算节点,如F-AP和用户,但这些节点分…

如何利用Cangaroo开源工具高效解决CAN总线开发难题

如何利用Cangaroo开源工具高效解决CAN总线开发难题 【免费下载链接】cangaroo 项目地址: https://gitcode.com/gh_mirrors/ca/cangaroo 在汽车电子和工业控制领域&#xff0c;CAN总线开发常常面临数据解析复杂、多接口管理困难等挑战。Cangaroo作为一款专业的开源CAN总…

LPrint:一款跨平台标签打印工具的终极解决方案

LPrint&#xff1a;一款跨平台标签打印工具的终极解决方案 【免费下载链接】lprint A Label Printer Application 项目地址: https://gitcode.com/gh_mirrors/lp/lprint 在现代数字化工作环境中&#xff0c;跨平台标签打印一直是困扰企业和个人的技术难题。从物流仓储到…

为什么FMPy成为工程师首选的FMU仿真解决方案?

为什么FMPy成为工程师首选的FMU仿真解决方案&#xff1f; 【免费下载链接】FMPy Simulate Functional Mockup Units (FMUs) in Python 项目地址: https://gitcode.com/gh_mirrors/fm/FMPy 在当今复杂系统建模与仿真领域&#xff0c;FMPy作为一款专业的Python FMU仿真工具…

Vue3甘特图组件深度解析:构建高性能项目管理界面的终极方案

Vue3甘特图组件深度解析&#xff1a;构建高性能项目管理界面的终极方案 【免费下载链接】gantt An easy-to-use Gantt component. 持续更新&#xff0c;中文文档 项目地址: https://gitcode.com/gh_mirrors/gantt/gantt 在数字化项目管理时代&#xff0c;甘特图作为任务…

会议整理从30分钟到5分钟:通过TicNote AI 录音卡片,我在职场效率直接开挂 !

作为程序员&#xff0c;也作为领导&#xff0c;每次在对接需求的时候总是要一边努力倾听&#xff0c;一边疯狂打字记录&#xff0c;结果不仅漏掉了关键信息&#xff0c;被提问时还一头雾水&#xff0c;就是因为记录不及时&#xff0c;毕竟说话的速度远远大于记录的速度&#xf…

百度网盘秒传脚本完全指南:快速上手极速生成功能

百度网盘秒传脚本是一款高效的网盘文件管理工具&#xff0c;通过模拟官方秒传机制实现文件的快速分享和转存。这款免费工具的核心优势在于永久保证分享有效性&#xff0c;且链接不包含任何账号隐私信息。本文将为您提供完整的秒传脚本使用教程。 【免费下载链接】rapid-upload-…

移动端PDF预览技术深度解析:从问题根源到最佳实践

移动端PDF预览技术深度解析&#xff1a;从问题根源到最佳实践 【免费下载链接】pdfh5 项目地址: https://gitcode.com/gh_mirrors/pdf/pdfh5 在移动互联网高速发展的今天&#xff0c;PDF文档的移动端预览已成为刚需&#xff0c;但传统方案在性能、交互和兼容性方面存在…

智能agent研究误区:从技术错觉到实际应用的挑战

先给结论&#xff1a;有搞头&#xff0c;但前提是你别把 agent 当成“调 API 的集合体”。先给结论&#xff1a;有搞头&#xff0c;但前提是你别把 agent 当成“调 API 的集合体”。先给结论&#xff1a;有搞头&#xff0c;但前提是你别把 agent 当成“调 API 的集合体”。重要…

OpenWrt磁盘管理终极指南:luci-app-diskman完整使用教程

OpenWrt磁盘管理终极指南&#xff1a;luci-app-diskman完整使用教程 【免费下载链接】luci-app-diskman Disk Manager for LuCI 项目地址: https://gitcode.com/gh_mirrors/lu/luci-app-diskman 想要轻松管理OpenWrt系统的磁盘存储吗&#xff1f;luci-app-diskman作为专…

并查集示例

并查集 “合并&#xff08;Union&#xff09; 查找&#xff08;Find&#xff09;”的集合&#xff0c;也叫 Disjoint Set Union&#xff08;DSU&#xff09;。 它只做两件极快的事&#xff1a; Find(x) – 问“x 在哪个集合&#xff1f;”→ 返回根节点Union(x, y) – 把 x 所…

PlayCover深度解析:在Apple Silicon Mac上运行iOS游戏的技术实践

PlayCover深度解析&#xff1a;在Apple Silicon Mac上运行iOS游戏的技术实践 【免费下载链接】PlayCover Community fork of PlayCover 项目地址: https://gitcode.com/gh_mirrors/pl/PlayCover 技术架构与实现原理 PlayCover作为专为Apple Silicon架构设计的开源解决方…

Flutter 状态管理终极指南(2025 版):从 setState 到 Riverpod 3.0,如何做出正确选择?

作者&#xff1a;Qwen 首发平台&#xff1a;CSDN 关键词&#xff1a;Flutter 状态管理 / Riverpod 3.0 / Bloc 8.0 / Provider / 架构设计 引言&#xff1a;为什么状态管理是 Flutter 项目的“命门”&#xff1f; 在 Flutter 开发中&#xff0c;UI 的构建只是表象&#xff0c;…

让程序帮孩子更好的认识这个世界

让程序帮孩子更好地认识这个世界距离第一次少儿编程课已经一周了&#xff0c;我们聊一下后续学习的反馈。同时也有一些感悟和心得&#xff0c;一起在这里和大家聊一聊。键盘不熟悉&#xff0c;打字速度比较慢一个小学生&#xff0c;还处在用铅笔写字的阶段&#xff0c;基本上对…