waitpid返回ECHILD -但是pid是有效的
waitpid returns ECHILD - but pid was valid
我有一个程序,生成其他进程execve:
s32 ret = execve( argv[0], argv.data(), (char* const*) req.posixEnv() );
然后在循环中调用waitpid来观察进程何时终止:
while( 1 )
{
readOutputFromChildProcess( pid );
int status;
s32 retPid = waitpid( pid, &status, WNOHANG );
if ( retPid < 0 )
{
if ( errno == ECHILD )
{
// I don't expect to ever get this error - but I do. why?
printf( "Process gone before previous wait. Return status lost.n" );
assert(0);
} else {
// other real errors handled here.
handleError();
break;
}
}
if ( retPid == 0 )
{
waitSomeTime();
continue;
}
processValidResults( status );
break;
}
我极大地简化了代码。我的理解是,一旦生成一个进程,进程表项将一直保留,直到调用者调用"waitpid"并获得一个大于零的返回值和一个有效的返回状态。
但是在某些情况下似乎发生的是进程自己终止,当我调用waitpid时,它返回-1,错误ECHILD
ECHILD意味着当我调用waitpid时,进程表中没有具有该id的进程。所以要么我的pid是无效的——我已经仔细检查过了——它是有效的。
或- waitpid在此进程结束后已被调用-在这种情况下,我无法从此进程获得返回代码。
程序是多线程的。我还检查了我没有太早调用waitpid。它会在几次"等待"之后发生。
是否有其他方法可以在不调用waitpid的情况下清理进程表项?我怎样才能确保我总是得到返回码?
@显式忽略SIGCHLD:
好的,所以我理解显式忽略它会导致waitpid()失败。我没有显式地忽略它,但我确实设置了一些信号处理程序来在另一个地方捕获崩溃,如下所示:
void kxHandleCrashes()
{
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = abortHandler;
sigemptyset( &sa.sa_mask );
sigaction( SIGABRT, &sa, NULL );
sigaction( SIGSEGV, &sa, NULL );
sigaction( SIGBUS, &sa, NULL );
sigaction( SIGILL, &sa, NULL );
sigaction( SIGFPE, &sa, NULL );
sigaction( SIGPIPE, &sa, NULL );
// Should I add aline like this:
// sigaction( SIGCHLD, &sa, NULL );
}
我有类似的问题- waitpid将失败与ECHLD。子进程正在运行,我没有接触SIGCHLD处理程序(默认处理程序),但每次仍然在waitpid上获得ECHLD。
经过几个小时的调查发现,原来是我把孩子分出来,然后妖魔化父母(父母分出来),这实际上把所有的孩子都变成了孤儿。
我将父进程的守护进程移到fork子进程之前,这样一切就开始完美地工作了。
如果你得到这个神秘的ECHLD错误,你没有弄乱SIGCHLD信号处理程序-检查这些孩子是否仍然是你的孩子,孩子的PPID等于父母的PID
您的程序示例缺少一条重要信息:如何声明errno
您应该确保包含errno.h
。
请参考线程安全和POSIX.1中errno的重新定义一节。
- 欧拉项目#8答案是大以获得有效答案
- 调整大小后指向元素值的指针unordered_map有效?
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- GCC对可能有效的代码抛出init list生存期警告
- 有效地使用std::unordered_map来插入或增加键的值
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 自定义先决条件对移动分配运算符有效吗
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- 为什么这种直接初始化有效?(C++17)
- 使用 VID、PID、+SN 查找 USB 端口号
- 递归函数有效,但无法记忆
- 在C++中初始化向量映射的最有效方法
- 如果变量名称不跟在 char* 后面,const char* 是否有效?
- 钳制迭代器是否有效
- 如何有效地在 std::vector 中插入一对?
- 对于四轴飞行器,PID中I控制器的理想值应该是多少
- waitpid返回ECHILD -但是pid是有效的