Linux下waitpid()使用WEXITED参数为何报EINVAL错误?
waitpid()设置WEXITED报错EINVAL的原因及正确用法
我编写了一个名为waitpidx.cpp的程序(代码如下),在Ubuntu Linux 20.04和22.04系统中运行时,调用waitpid()并设置waitflags=WEXITED会失败,报错errno=22(EINVAL);但将waitflags设为0时,waitpid()可成功执行。根据man waitpid手册,WEXITED的作用是等待已终止的子进程,我认为waitflags=0与waitflags=WEXITED含义应一致,想请教使用WEXITED出错的原因及它的正确使用场景。
程序代码
#include <unistd.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <sys/wait.h> int main(int argc, char* argv[]) { pid_t child_pid = fork(); if (child_pid != 0) { printf("Parent process: getpid()=%d\n", (int)getpid()); int wstatus = 0; int waitflags = WEXITED; // 0 is OK, but WEXITED not OK. pid_t wpid = waitpid(child_pid, &wstatus, waitflags); if (wpid == -1) { printf("waitpid() fail. errno=%d, %s\n", errno, strerror(errno)); exit(4); } assert(wpid == child_pid); printf("Parent process waitpid(,,%d) success.\n", waitflags); exit(0); } // Child process printf("Child process: getpid()=%d\n", (int)getpid()); sleep(1); }
问题解答
报错原因
WEXITED并不是waitpid()函数的合法参数,它属于waitid()函数的参数体系:
- 查看
waitpid(2)手册可知,其第三个参数options仅支持WNOHANG、WUNTRACED、WCONTINUED等少数常量,WEXITED不在此列。 WEXITED是专门给waitid()使用的常量,用于指定等待已退出的子进程类型。当你把它传给waitpid()时,内核会判定这是一个无效的flags值,直接返回EINVAL错误。waitpid()的默认行为(flags=0)确实是等待已终止的子进程,这和你对WEXITED的预期效果一致,但二者分属不同函数的参数体系,不能混用。
WEXITED的正确使用场景
WEXITED只能配合waitid()函数使用,示例代码如下:
#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { pid_t child_pid = fork(); if (child_pid > 0) { siginfo_t info; // 使用waitid等待已退出的子进程,效果等价于waitpid(child_pid, &wstatus, 0) int ret = waitid(P_PID, child_pid, &info, WEXITED); if (ret == -1) { perror("waitid failed"); exit(EXIT_FAILURE); } printf("Child process exited, PID: %d\n", info.si_pid); } else if (child_pid == 0) { sleep(1); exit(EXIT_SUCCESS); } else { perror("fork failed"); exit(EXIT_FAILURE); } return 0; }
内容的提问来源于stack exchange,提问作者Jimm Chen
相关产品推荐
相关产品推荐

