2016-11-20 15 views
0

Sierraの前に、元のプロセスをフォークした後、子プロセスでGLUTを初期化できるようにしました。 Sierraの最新バージョンでは、これは変更されたようです。次のプログラムは、セグメント化エラーでクラッシュします。代わりにすべてのglut関数を親プロセスに移動すると、すべてが機能します。親/子プロセスの使用に違いがあるのはなぜですか?OSX Sierraでforkした後のGLUTの使用

#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()それは、フォークプロセスをスレッドを作成されていません。フォークを呼び出した後は、ほぼ同じアドレス空間の内容を持つ2つのプロセスがありますが、それらのアドレス空間は互いに保護されています。 fork()に関する一般的なルールは、フォークの子プロセスの後で行う唯一の感覚的なことは、プロセスイメージをexecve()に置き換えることです。他に何かをするには、プログラムの設計において多くの先見が必要です。

スレッドの作成方法が異なります。あなたのプログラミング言語で提供されている実際のスレッドプリミティブを使用することをお勧めします。

これは、多くのOSやGUIライブラリでは、プロセスのGUI部品がメインスレッドで実行されるため、その理由の一部になる可能性もあります。また、OpenGLとマルチスレッドはちょっと厄介なことに注意してください。

+0

フォーク/スレッドをミックスすることについて申し訳ありません。しかし、それは私の質問に答える。なぜ私は親プロセスでGLUTしか使用できないのですか? – hanno

+1

@hanno: 'fork()'の使用に関するいくつかの警告があります。あなたの質問は重複して解説されています。また、この記事を見てみるといいかもしれません:http://www.evanjones.ca/fork-is-dangerous.html - 理論的には 'fork( ) '' '' '' '' '' '' 'システム全体のロックが仮想' fork() 'クリティカルセクションを認識している機構を介して行われる場合にのみ、これは、いくつかの異なるロッキング・プロバイダを使用する可能性のある十分に複雑なプログラムの場合は当てはまりません。 – datenwolf

関連する問題