3

これはfork()で簡単ですが、MMUがありません。vfork()は、子が終了するかexec()を実行するまで、親プロセスをブロックすると聞きました。どうすればこのようなことを達成できますか?:

pid_t pid = vfork();

if (pid == -1) {
    // fail
    exit(-1);
}

if (pid == 0) {
    // child
    while(1) {
        // Do my daemon stuff
    }

    // Let's pretend it exits sometime
    exit();
} 

// Continue execution in parent without blocking.....
4

3 に答える 3

3

MMU と fork() を使用しない uClinux システム用の daemon() 関数、Jamie Lokier 作、パッチ形式

vfork() で daemon() を実行することはできません。vfork() を使用して !MMU でデーモンに似たものを作成するには、親プロセスは停止せず (余分なプロセスが存在するため)、バックグラウンドでデーモンを呼び出す必要があります (つまり、& をシェル)。

一方、Linux では clone() が提供されています。知識と注意があれば、!MMU 用の daemon() を実装できます。Jamie Lokier には、ARM と i386 でそれを行う機能があります。ここから入手してください。

編集: !MMU Linux の Jamie Lokier の daemon() へのリンクをより目立つようにしました。

于 2010-10-08T19:46:42.760 に答える
3

ここにあるのとまったく同じようにこれを行う方法はないようです。 execまたは_exit、親が実行を継続するために呼び出される必要があります。デーモンコードを別の実行可能ファイルに入れるかexec、子を使用して元のタスクを生成します。2 番目のアプローチは卑劣な方法であり、ここで説明されています。

于 2010-10-08T18:51:30.133 に答える
1

これは他の多くの人が以前に遭遇したタイプの問題であると私は思っていたでしょうが、「親を殺す」問題について話している人を見つけるのに苦労しました.

私は当初、次のように (それほどではありませんが、一種の) への単純な呼び出しでこれを実行できるはずだと考えていましたclone

pid_t new_vfork(void) {
    return clone(child_func,        /* child function */
                 child_stack,          /* child stack    */
                 SIGCHLD | CLONE_VM,   /* flags */
                 NULL,                 /* argument to child */
                 NULL,                 /* pid of the child */
                 NULL,                 /* thread local storage for child */
                 NULL);                /* thread id of child in child's mem */
}

ただし、child_stack と child_func が vfork の場合と同じように機能するかどうかを判断するのは非常に困難です。というのは、child_func はクローン呼び出しからのリターン アドレスである必要があり、child_stack は、実際のシステム コール (sys_clone) が行われます。

あなたはおそらくsys_clone直接呼び出すことを試みることができます

pid_t new_vfork(void) {
    return sys_clone( SIGCHLD | CLONE_VM, NULL);
}

あなたが望むものを手に入れることができると思います。child_stack ポインターである 2 番目の引数として NULL を渡すと、カーネルは vfork および fork と同じことを行い、親と同じスタックを使用します。

私はsys_clone直接使用したことがなく、これをテストしていませんが、うまくいくはずです。私は信じている:

  sys_clone( SIGCHLD | CLONE_VM | CLONE_VFORK, NULL);

と同等vforkです。

これが機能しない場合 (そして、似たようなことを行う方法がわからない場合) は、通常の clone 呼び出しをsetjumpandlongjmp呼び出しと一緒に使用してエミュレートするか、必要性を回避できる可能性があります。forkとの「2 回戻る」セマンティクスvfork

于 2010-10-08T20:52:52.253 に答える