在OSX Sierra上使用fork后使用GLUT

时间:2016-11-20 00:05:00

标签: multithreading macos opengl glut macos-sierra

在Sierra之前,我曾经能够在分配原始进程后初始化子进程上的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

1 个答案:

答案 0 :(得分:0)

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

以不同的方式创建线程。我建议你使用你选择的编程语言提供的实际线程原语。

话虽这么说,许多操作系统和GUI库都需要一个过程&#39; GUI部分在主线程中运行,因此也可能是部分原因。还要注意OpenGL和多线程有点挑剔。