4

私はプログラムを書いています。ボタンが押されると、サーバー プロセスを実行する必要があります (これは、彼を殺すことにした場合にのみ停止します)。
このプロセスを実行するために、fork/execv メカニズムを使用することにしました。

void Command::RunServer() {

    pid = fork();

    if (pid==0) {
        chdir("./bin");
        char str[10];
        sprintf(str,"%d",port);
        char *argv[] = {"./Server", str};
        execv("./Server",argv);
    }
    else {
        config->pid = pid;
        return;
    }
}

そして、「ボタンを押した」メソッドでは、次のことを行います。

command->RunServer();

数日前はうまく機能しているように見えました...そして今はエラーが発生します:

main: xcb_io.c:221: poll_for_event: Assertion `(((long) (event_sequence) - (long) (dpy->request)) <= 0)' failed.

pthread に切り替えてみるべきですか? 私は何か悪いことをしましたか?

ありがとう、
えお

4

2 に答える 2

5

fork()プロセスのすべてのファイル記述子を実行すると、新しいファイル記述子が複製されます。またexec*()、フラグでマークされていない限り、すべてのファイル記述子も保持されますFD_CLOEXEC

私の推測では、一部のライブラリ (おそらく Xlib) で使用されている一部の fd が新しいプロセスに継承されており、重複がプログラムに混乱を引き起こしていると思われます。

このような場合、標準 I/O を開いたままにしておくには、BSD 関数closefrom()( ) が役立ちます。closefrom(3)残念ながら、Linux にはそのような機能がないため、close-all ループまたは同様の処理を実行する必要があります。

int open_max = sysconf (_SC_OPEN_MAX);
for (int i = 3; i < open_max; i++)
    close(i);

この問題の詳細については、こちらをご覧ください。

于 2012-07-19T08:37:07.903 に答える
3

への呼び出しexecvargvは、ヌル ポインタで終了する必要があります。前の行は次のようになります。

char* argv[] = { "./Server", str, NULL };
于 2012-07-19T09:21:19.803 に答える