vForkを使用してUCLINUXでデーモンをスポーンするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/3893293

  •  28-09-2019
  •  | 
  •  

質問

これは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.....
役に立ちましたか?

解決

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

他のヒント

MMUおよびFork()のないUCLINUXシステムのDaemon()機能、Jamie Lokier、パッチ形式で

vfork()でdaemon()を実行することはできません。 vfork()を使用してデーモンに似たものを作成するには、親プロセスが死なない(追加のプロセスがあります)。シェル)。

一方、Linuxはclone()を提供します。それで武装して、知識とケアでは、!mmuのdaemon()を実装することが可能です。 Jamie Lokierには、ARMとI386でそれを行う機能があります。 ここ.

編集: Jamie LokierのDaemon()へのリンクを!MMU Linuxのより顕著にしました。

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

私は最初、あなたが(そうではないが、ある種の)簡単な呼び出しでこれを行うことができるはずだと思った 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はクローンコールからの返品アドレスであり、子ども_stackがスタックのトップである必要があるため、かなり困難です。実際のシステムコール(SYS_CLONE)が作成されます。

おそらく電話しようとすることができます sys_clone 直接

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

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

私は使用したことがありません sys_clone 直接テストしていませんが、機能するはずだと思います。私は信じている:

  sys_clone( SIGCHLD | CLONE_VM | CLONE_VFORK, NULL);

に相当します vfork.

これが機能しない場合(そして、あなたが似たようなことをする方法を理解できない場合)、あなたは一緒に通常のクローンコールを使用できるかもしれません setjumplongjmp それをエミュレートするための呼び出し、またはあなたは「リターンの2回」セマンティクスの必要性を回避できるかもしれません forkvfork.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top