我在OS X 10.10.5和Xcode 7.2上。我有一个程序产生一个子进程来使用OpenGL / GLUT运行可视化,即
pid_t childpid;
childpid = fork();
if(childpid == 0) { // this is the child process
glutInit(&argc, argv);
...
}
else{ // this is the parent process that does something else
...
}
当我在Xcode中运行时,程序永远不会从glutInit返回。相反,我使用父进程进行可视化,而子进程运行其他所有内容,即
if(childpid != 0) { // this is the parent process
glutInit(&argc, argv);
...
}
...
然后弹出OpenGL窗口,整个程序运行正常。另外,如果我在Xcode之外的终端中使用Makefile构建时运行原始版本(子项进行可视化),一切运行正常。
关于可能导致这种情况的任何想法?
我无法在Xcode中调试很多东西,因为调试器始终遵循父进程。如果我尝试通过Debug-> Attach to process附加到子进程,我会收到一个错误:“Xcode无法附加到”J2“。”J2“不支持可调试的体系结构。”我在最后一个附加到xcode中的其他进程的问题上发现了一些问题,但这些解决方案并不适用于我。
答案 0 :(得分:2)
除了fork()
或{{1}之外的某些exec()
,您无法在_exit()
的子级方面执行 任何 }。
我将引用Leopard CoreFoundation Framework发行说明。我不知道他们是否还在线,因为Apple倾向于替换而不是扩展Core Foundation发行说明。
CoreFoundation和fork()
由于fork()的行为,CoreFoundation无法使用 fork()的子端。如果你fork(),你必须跟着它 某种exec *()调用,你不应该使用CoreFoundation API 在孩子内部,在exec *()之前。适用于所有更高级别 使用CoreFoundation的API,因为你不知道那些是什么 更高级别的API正在做,以及他们是否正在使用CoreFoundation API,您也不应该使用任何更高级别的API。这包括 使用守护进程()函数。
此外,根据POSIX,只有异步取消安全功能才是安全的 在fork()的子端使用,所以即使使用较低级别 libSystem / BSD / UNIX API应保持在最低限度,理想情况下应保持最低限度 只有异步取消安全功能。
这一直都是事实,并且已经有了这样的说明 过去各种Cocoa开发人员填写清单。但CoreFoundation 现在采取一些更强有力的措施来“强制执行”这一限制,所以 我们认为添加发行说明来调用它是值得的 也是。当某些东西使用API时,会向stderr写入一条消息 这绝对是知道在CoreFoundation之后不安全的 叉子()。但是,如果文件描述符2已经关闭,那么你将得不到 消息或通知,这太糟糕了。我们试图制作流程 以一种非常容易识别的方式终止,并做了一段时间,那是 非常方便,但向后的二进制兼容性使我们无法做到 如此。
换句话说,除了执行新程序之外,在fork()
的子方面做任何事情从来都不安全。
除了一般的POSIX禁令之外,经常提到的解释是:a)几乎所有的Cocoa程序现在都是多线程的,GCD之类的东西也是如此。 B)当你fork()
时,只有调用线程存活到子进程中;其他线程只是消失了。由于这些线程可能一直在操纵共享资源,因此子进程不能依赖于健全状态。例如,malloc()
实现可能具有锁定以保护共享结构,并且在fork()
时,锁定可能已由其中一个已经过去的线程保留。因此,如果剩下的线程试图分配内存,它可能会无限期挂起。其他共享数据结构可能只是处于损坏状态。等