当作为子进程运行时,OpenGL 窗口不会在 xcode (7.2) 中打开
Posted
技术标签:
【中文标题】当作为子进程运行时,OpenGL 窗口不会在 xcode (7.2) 中打开【英文标题】:OpenGL window doesn't open in xcode (7.2) when run as a child process 【发布时间】:2016-01-16 02:18:26 【问题描述】:我使用的是 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 之外的终端中使用 Makefiles 构建时运行原始版本(让孩子进行可视化),一切运行正常。
关于什么可能导致这种情况的任何想法?
我无法在 Xcode 中调试很远的东西,因为调试器总是跟随父进程。如果我尝试通过 Debug->Attach to process 附加到子进程,我会收到错误消息:“Xcode 无法附加到“J2”。“J2”不支持可调试架构。”我发现了关于在 xcode 中附加到其他进程的最后一期的一些问题,但解决方案对我不起作用。
【问题讨论】:
【参考方案1】:除了exec()
或_exit()
之外,您不能在fork()
的子端做任何事情。
我将引用 Leopard CoreFoundation 框架发行说明。我不知道它们是否仍然在线,因为 Apple 倾向于替换而不是扩展 Core Foundation 发行说明。
CoreFoundation 和 fork()
由于 fork() 的行为,CoreFoundation 不能用于 fork() 的子端。如果你 fork(),你必须跟随它 exec*() 调用某种形式,你不应该使用 CoreFoundation API 在孩子内部,在 exec*() 之前。适用于所有更高级别 使用 CoreFoundation 的 API,因为你不知道那些 更高级别的 API 正在做什么,以及它们是否使用 CoreFoundation API,您也不应该使用任何更高级别的 API。这包括 使用 daemon() 函数。
此外,根据 POSIX,只有异步取消安全函数是安全的 在 fork() 的子端使用,因此即使使用较低级别 libSystem/BSD/UNIX API 应该保持在最低限度,理想情况下是 只有异步取消安全功能。
这一直是正确的,并且已经对此进行了注释 过去的各种 Cocoa 开发者邮件列表。但是CoreFoundation 现在正在采取一些更强有力的措施来“执行”这个限制,所以 我们认为值得添加一个发布说明来调用它 也出来了。当某些东西使用 API 时,一条消息被写入 stderr 这在 CoreFoundation 之后肯定是不安全的 叉()。但是,如果文件描述符 2 已关闭,您将不会得到 消息或通知,这太糟糕了。我们试图制作流程 以一种非常容易识别的方式终止,并做了一段时间,那就是 非常方便,但向后二进制兼容性阻止了我们做 所以。
换句话说,除了执行一个新程序之外,在fork()
的子方做很多事情从来都不是安全的。
除了一般的 POSIX 禁令之外,经常提到的解释是:a) 现在几乎所有的 Cocoa 程序都是多线程的,比如 GCD 等等。 B)当你fork()
时,只有调用线程存活到子进程中;其他线程就消失了。由于这些线程可能一直在操纵共享资源,因此子进程不能依赖于具有健全的状态。例如,malloc()
实现可能有一个锁来保护共享结构,并且在fork()
时,该锁可能已由一个现已消失的线程持有。因此,如果剩余线程尝试分配内存,它可能会无限期挂起。其他共享数据结构可能只是处于损坏状态。等等。
【讨论】:
谢谢!那么使用 Makefiles 手动构建所有东西时它工作正常的原因是 Xcode 在幕后做更复杂的事情吗? 我不知道为什么它在某些情况下似乎“工作正常”,但无论如何你都不能依赖它。在fork()
的子方做事的危险性质本质上是不可预测的。没有保证在任何给定的运行中肯定会出错。只是也不能保证他们会走对路。以上是关于当作为子进程运行时,OpenGL 窗口不会在 xcode (7.2) 中打开的主要内容,如果未能解决你的问题,请参考以下文章
PyQt5 窗口在运行几秒钟后自动关闭 - “进程以退出代码 -1073741819 (0xC0000005) 完成”
进程完成,退出代码 -1073740791 (0xC0000409) 错误未打开网站
尝试使用 OpenCV 库运行示例代码后,进程以退出代码 -1073741515 (0xC0000135) 完成