微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

fork + wait在OSX上获取EINTR

我在叉101失败。我期望这分叉一个subprocess,并输出子和父printfs:

pid_t fpid; if ((fpid = fork()) < 0) { printf("fork: %sn",strerror(errno)); exit(-1); } if (0 == fpid) // child { printf("nI am the childn"); } else { printf("nI am the parentn"); pid_t wpid; while ((wpid = waitpid(WAIT_ANY,NULL,0))) { if (errno == ECHILD) break; else if (wpid < 0) printf("wait: %sn",strerror(errno)); } }

相反,我得到这个输出

我是父母

等待:中断系统调用

Windows 8应用程序WebView捕获事件目标=“_ blank”

用C ++有效地阅读一个非常大的文本文件

C ++:如何正确地注册和注销我们的应用程序的文件types关联(编程)

dos.h for Linux?

从C ++ CreateProcess启动Windows批处理具有不同的行为

所以我的问题是:为什么孩子没有机会去生活和跑步? 请不要有人想到孩子! 另外,EINTR从哪里来? 显然,这与我的第一个问题有某种关系。

而且,当我在一个独立的程序中运行这个代码时,它可以正常工作,但是当我在一个更大的程序中运行时, 更大的程序可能会怎样使waitpid失望呢?

FWIW这是在OSX 10.9上。

与cmake,icc和pthreads(linux)链接

C ++:获取不正确的文件大小

如何在Linux内核中打印当前线程堆栈跟踪?

一种不知道签名的C函数调用方法

任何人都可以想到一个简单的方法来创build一个套接字的线程?

在OSX上,在/不允许的情况下在fork的子节点上做很多事情是不合法的。 请参阅叉子手册页底部的警告。 安全函数列表位于sigaction(2)手册页上 。 printf()不在其中。

此外,标准输出可能被缓冲。 printf()的结果可能不会被刷新。 如果你调用了exit() ,它会被刷新,但是这在叉子的子面也是不合法的。 (使用_exit()是合适的,但是不会刷新打开的流。)就这样,您似乎不会退出您的子进程,这意味着执行流将继续到您显示代码调用者,大概回到你的程序的其余部分。 由于叉子的儿童侧面的限制,可能会卡在那儿。

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

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

最后,我认为你应该传递fpid而不是WAIT_ANY到waitpid() 。 你有一个特定的子进程,你想等待。 在一个更大的程序的情况下,你不想窃取其他子组件产生的孩子终止的通知。 而且你总是需要绕过可中断的系统调用,直到它们返回EINTR以外的东西。

只有检查errno是否被指示,例如通过系统调用返回-1 。

代码应该如下所示:

pid_t fpid; if ((fpid = fork()) < 0) { printf("fork: %sn",0))) { if (-1 == wpid) { perror("waitpid() Failed"); } else if (wpid == fpid) { /* My child ended,so stop waiting for it. */ break; } } }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐