vForkを使用してUCLINUXでデーモンをスポーンするにはどうすればよいですか?
質問
これは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
.
これが機能しない場合(そして、あなたが似たようなことをする方法を理解できない場合)、あなたは一緒に通常のクローンコールを使用できるかもしれません setjump
と longjmp
それをエミュレートするための呼び出し、またはあなたは「リターンの2回」セマンティクスの必要性を回避できるかもしれません fork
と vfork
.