当作为子进程运行时,OpenGL窗口不会在xcode(7.2)中打开

时间:2016-01-16 02:18:26

标签: c xcode opengl multiprocessing glut

我在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中的其他进程的问题上发现了一些问题,但这些解决方案并不适用于我。

1 个答案:

答案 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()时,锁定可能已由其中一个已经过去的线程保留。因此,如果剩下的线程试图分配内存,它可能会无限期挂起。其他共享数据结构可能只是处于损坏状态。等