2010-11-19 2 views
8

状況: 私はCで書かれたマルチスレッドプログラムを持っています。スレッドの1つがforkすると、exec()を使用して子プロセスが別のプロセスに置き換えられ、親プロセスが子プロセスを終了するのを待ちます。C - execはマルチスレッドプロセスでforkをすぐに実行する必要がありますか?

問題: 子プロセスがフォークによって作成された後()は、次のexec()コマンドで使用される引数をコンパイル数行のコードがあります。

仮説 私は子プロセスの間の時間にフォーク(によって作成されたと仮定して訂正)とexec()、子プロセスに置き換えられアム - 親のコピーであること - がありますすべてのこれらのスレッドは非常に短期間ではありますが実行されますか?

もしそうなら、fork()の直後にexec()を呼び出す正しい解決策はありますか?

答えて

9

forkを呼び出すスレッドだけが、新しいプロセスで実行されます。ただし、execの前に呼び出すことができる関数には制限があります。 fork

プロセスは、単一スレッドの で作成されます。マルチスレッドの プロセスがfork()を呼び出す場合、新しいプロセス は、 スレッドとそのアドレス空間全体の複製、 (可能であれば ミューテックスおよびその他のリソースの状態を含む)のレプリカを含むものとします。 したがって、エラーを回避するために、子プロセスはの非同期シグナル安全操作を実行することがあります。これは、関数の1つである が呼び出されるまでです。 が呼び出されます。フォーク ハンドラは、のpthread_atfork()の機能によって確立され、 のアプリケーションを維持するために の呼び出しをfork()の呼び出しで無効にすることができます。

は、私は、これは任意のマルチスレッド ライブラリが正しくpthread_atforkを使用すると、あなたが一般的に限り、大丈夫でなければなりません意味と考えています。

EDIT:pthread_atforkページライブラリは自身を保護する方法をさらに説明しています

予想される使用が準備 ハンドラは、すべてのミューテックスのロックを取得し、 他の二つのフォークハンドラが にそれらを解放ということです。

たとえば、アプリケーションが は、このように子供がの 一貫性のあるスナップショットを取得することを保証し、 必要ミューテックスそれらのミューテックスを解放 ルーチンを維持し、供給子と親 ライブラリを取得 準備ルーチンを供給することができますが のライブラリの状態です(そして、ミューテックスは のままです)。あるいは、いくつかの ライブラリは、いくつかの既知の値 に、ライブラリ内の ミューテックス、すべての 関連した状態を再初期化だけ 子ルーチンを供給することができるかもしれない(例えば、それが何だったか 画像は元々実行されたとき)。

+0

標準ライブラリ(例えば、stdio、 'atexit'、' malloc'、スレッドの作成と破壊など)は、内部的に同期リソースを使用している可能性があります。フォーク '?もしそうなら、 'pthread_atfork'の使用はどのように問題を解決するでしょうか? –

+0

@R、はい、おそらく。それはライブラリによって異なります。場合によっては、すべてのミューテックスをプリフォークでロックし、フォーク直後に解放することができます。他のものでは、あたかもプロセスが最初から始まったかのように再初期化するだけでいいです。私は 'pthread_atfork'から関連する箇所を追加しました。 –

3

@Matthewさんが答えて書いたように、親プロセスの他のスレッドは子プロセスに存在しません(あなたがPThreadを使用している場合)。

これがそうでなければ、exec()呼び出しをforkの直後に置くことは役に立たないことに注意してください。これは、呼び出しの前に他のスレッドが実行される可能性があるためです。 exec()。しかし、fork()を呼び出す前にmutexをロックすることでこれを制御することができます。これは基本的にexec()の呼び出しによって破壊されます。

+0

+1 2番目の段落の説明を参照してください。 –

+0

mutexが "本質的に破壊されている"ことについてこれが正しいのか分かりません。上で述べたように、ロックが矛盾した状態になる危険性があります。そのため、 'pthread_atfork'が存在します。 –

0

私はあまりにも考えて、すべてのスレッドも子プロセスでレプリケートされます。しかし、それは真実ではありません。他のスレッドは子プロセスでは複製されないため、execの前にmutexes/locksを使用している場合は、forkハンドラがそれらを適切に処理するように記述する必要があります。 ここに記事があります。 http://learnwithtechies.com/tech/index.php?option=com_content&view=article&id=15:fork-in-multithreaded-environment&catid=10:unix

関連する問題