2016-11-20 79 views
0

在Sierra之前,我曾经能够在分支原始进程之后初始化子进程上的GLUT。随着最新版本的Sierra,这似乎已经改变。以下程序因分段错误而崩溃。如果我反而将所有的过剩函数移动到父进程中,那么一切正常。为什么使用父/子过程有区别?在OSX上使用GLUT后使用GLUT Sierra

#include <stdlib.h> 
#include <GLUT/glut.h> 

void pass(void){ 
} 

int main(int argc, char* argv[]) { 
    pid_t childpid; 
    childpid = fork(); 
    if (childpid == 0){ 
     glutInit(&argc,argv); 
     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); 
     glutInitWindowSize(100,100); 
     glutCreateWindow("test"); 
     glutDisplayFunc(pass); 
     glGetError(); 
     glutMainLoop(); 
    }else{ 
     sleep(5); 
    } 
    exit(1); 
} 

分割的错,我得到:

Crashed Thread:  0 Dispatch queue: com.apple.main-thread 

Exception Type:  EXC_BAD_INSTRUCTION (SIGILL) 
Exception Codes:  0x0000000000000001, 0x0000000000000000 
Exception Note:  EXC_CORPSE_NOTIFY 

Termination Signal: Illegal instruction: 4 
Termination Reason: Namespace SIGNAL, Code 0x4 
Terminating Process: exc handler [0] 

Application Specific Information: 
BUG IN CLIENT OF LIBDISPATCH: _dispatch_main_queue_callback_4CF called from the wrong thread 
crashed on child side of fork pre-exec 

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 
0 libdispatch.dylib    0x00007fffe8e7bd21 _dispatch_main_queue_callback_4CF + 1291 
1 com.apple.CoreFoundation  0x00007fffd3c7bbe9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 
2 com.apple.CoreFoundation  0x00007fffd3c3d00d __CFRunLoopRun + 2205 
3 com.apple.CoreFoundation  0x00007fffd3c3c514 CFRunLoopRunSpecific + 420 
4 com.apple.Foundation   0x00007fffd57e1c9b -[NSRunLoop(NSRunLoop) limitDateForMode:] + 196 
5 com.apple.glut     0x0000000104f39e93 -[GLUTApplication run] + 321 
6 com.apple.glut     0x0000000104f46b0e glutMainLoop + 279 
7 a.out       0x0000000104f24ed9 main + 121 (main.c:18) 
8 libdyld.dylib     0x00007fffe8ea4255 start + 1 

回答

0

fork()不创建一个线程,它过程。在调用fork之后,您有两个地址空间内容几乎相同的进程,但是它们的地址空间是相互保护的。有关fork()的一般规则是,子进程中分叉后唯一可行的做法是用execve()替换进程映像;做其他事情需要程序设计中有很多先见之明。

线程的创建方式不同。我建议你使用你选择的编程语言提供的实际线程原语。这就是说,许多操作系统和GUI库都需要一个进程的GUI部件在主线程中运行,所以这也可能是原因的一部分。另外请注意,OpenGL和多线程是有点挑剔的。

+0

对不起混合叉/线程。但它回答了我的问题。为什么我只能在父进程中使用GLUT? – hanno

+1

@hanno:使用'fork()'有一些注意事项。你的问题已被封闭为重复,并给出了解释。您也可能想看看这篇文章:http://www.evanjones.ca/fork-is-dangerous.html - 应该指出,理论上可以适当地批判“叉” )'系统调用,如果(且仅当)所有锁定都通过意识到假设的'fork()'关键部分的机制发生;对于可能使用多个不同的锁定提供程序的任何足够复杂的程序,情况并非如此。 – datenwolf