在上一节我们学习了进程创建与退出,本节将深入Linux进程控制的核心环节——进程等待。如果你不妥善处理子进程的退出,它们就会变成僵尸进程,消耗系统资源。本文将手把手教你使用wait和waitpid函数,轻松管理子进程。
当子进程退出时,内核会保留其退出状态等信息,直到父进程来“收尸”。如果父进程一直忽略,子进程就会变成僵尸进程(Zombie)。僵尸进程已经终止,但仍占用进程表项,过多僵尸会拖垮系统。进程等待正是用来回收子进程资源、获取退出状态,避免僵尸进程泛滥。
#include
status:指向整型的指针,用于存储子进程退出状态。若不关心,可设为NULL。示例:使用wait函数回收子进程。
#include#include #include #include int main() { pid_t pid = fork(); if (pid == 0) { // 子进程 printf("子进程运行,PID=%d", getpid()); sleep(2); exit(42); } else if (pid > 0) { // 父进程 int status; pid_t ret = wait(&status); // 阻塞等待子进程退出 if (WIFEXITED(status)) { printf("子进程 %d 正常退出,退出码:%d", ret, WEXITSTATUS(status)); } } return 0;}
pid_t waitpid(pid_t pid, int *status, int options);
pid > 0:等待指定PID的子进程。pid = -1:等待任意子进程(同wait)。pid = 0:等待与父进程同组的任意子进程。pid < -1:等待组ID等于|pid|的任意子进程。WNOHANG,使调用非阻塞,若没有子进程退出立即返回0。waitpid函数提供了非阻塞选项,可以防止父进程被挂起,同时也能精确控制等待哪个子进程。
#include#include #include #include int main() { pid_t pid1 = fork(); if (pid1 == 0) { sleep(3); exit(1); } pid_t pid2 = fork(); if (pid2 == 0) { sleep(5); exit(2); } // 非阻塞等待特定子进程 int status; pid_t ret = waitpid(pid2, &status, WNOHANG); if (ret == 0) { printf("子进程 %d 尚未退出,继续做其他事...", pid2); } else if (ret > 0) { printf("子进程 %d 退出,状态=%d", ret, WEXITSTATUS(status)); } // 阻塞等待任意子进程 ret = waitpid(-1, &status, 0); // 等价于wait(&status) printf("任意子进程 %d 退出,退出码=%d", ret, WEXITSTATUS(status)); return 0;}
通过status可以获取子进程终止信息,常用宏:
WIFEXITED(status):子进程是否正常退出(如调用exit或main返回)。WEXITSTATUS(status):获取正常退出的退出码(低8位)。WIFSIGNALED(status):是否被信号终止。WTERMSIG(status):获取终止信号的编号。总的来说,waitpid函数功能更强大,是实际开发中的首选。掌握它,你就能彻底驾驭Linux进程控制,避免僵尸进程的困扰。
📌 本文涵盖的四个核心关键词:Linux进程控制、wait函数、waitpid函数、僵尸进程。希望通过本文,你对进程等待有了透彻的理解,并能灵活运用于实际编程。
本文由主机测评网于2026-03-03发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20260328476.html