gpt4 book ai didi

c - fork + wait 在 OSX 上获取 EINTR

转载 作者:太空狗 更新时间:2023-10-29 15:32:52 25 4
gpt4 key购买 nike

我在 fork 101 失败了。我希望这会 fork 一个子进程,并输出子进程和父进程 printfs:

pid_t fpid;

if ((fpid = fork()) < 0)
{
printf("fork: %s\n", strerror(errno));
exit(-1);
}

if (0 == fpid) // child
{
printf("\nI am the child\n");
}
else
{
printf("\nI am the parent\n");
pid_t wpid;
while ((wpid = waitpid(WAIT_ANY, NULL, 0)))
{
if (errno == ECHILD)
break;
else if (wpid < 0)
printf("wait: %s\n", strerror(errno));
}
}

相反,我得到了这个输出:

I am the parent

wait: Interrupted system call

所以我的问题是:为什么 child 得不到生存和奔跑的机会?请有人为 child 着想吧!另外,EINTR 从何而来?显然,这与我的第一个问题有某种关系。

此外,当我在独立程序中运行该代码时,它可以正常工作,但在我的大型程序中却不能;更大的程序可以做什么来扰乱 waitpid?

FWIW 这是在 OSX 10.9 上。

最佳答案

在 OSX 上,在执行之前/不执行之前在 fork 的子端做很多事情是不合法的。请参阅 fork man page 底部的警告.安全功能列表在 sigaction(2) man page 上. printf() 不在其中。

此外,stdout 可能已被缓冲。 printf() 的结果可能不会被刷新。如果您调用 exit(),它将被刷新,但这在 fork 的子端也是不合法的。 (使用 _exit() 是合适的,但这不会刷新打开的流。)实际上,您似乎没有退出子进程,这意味着执行流程继续到调用者您显示的代码的一部分,大概会返回到程序的其余部分。由于 fork 子端的限制,它可能会卡在那里。

如果你在 child 身上做这样的事情,你可能会有更多的运气:

const char msg[] = "\nI am the child\n";
write(STDOUT_FILENO, msg, sizeof(msg) - 1);
_exit(0);

最后,我认为您应该将 fpid 而不是 WAIT_ANY 传递给 waitpid()。您有一个特定的子进程要等待。在较大程序的上下文中,您不想窃取由其他子组件生成的子组件终止的通知。而且您始终需要循环可中断的系统调用,直到它们返回 EINTR 以外的内容。

关于c - fork + wait 在 OSX 上获取 EINTR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20555550/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com