forkを呼び出すときにスレッドはコピーされますか?


31

スレッドで実行しているプログラムがありfork()、UNIXベースのシステムを呼び出す場合、スレッドはコピーされますか?現在のプロセスの仮想メモリが、生成された新しいプロセスに1:1でコピーされることを知っています。スレッドがプロセスの仮想メモリに独自のスタックを持っていることを知っています。したがって、少なくともスレッドのスタックもコピーする必要があります。ただし、仮想メモリに存在しないためにコピーされないスレッドが他にあるかどうかはわかりません。ない場合、2つのプロセスはスレッドを共有していますか、それとも独立したコピーですか?

回答:


29

番号。

スレッドはにコピーされませんfork()。POSIX仕様によると(強調は私のものです):

fork-新しいプロセスを作成する

プロセスは単一スレッドで作成されます。マルチスレッドプロセスがfork()を呼び出す場合、新しいプロセスには、呼び出しスレッドのレプリカとその全体のアドレス空間が含まれます(ミューテックスやその他のリソースの状態を含む場合があります)。したがって、エラーを回避するために、子プロセスは、exec関数の1つが呼び出されるまで、非同期シグナルに対して安全な操作のみを実行できます。

この問題を回避するためpthread_atfork()に役立つ機能があります。


7

マンフォーク

子プロセスは、fork()を呼び出した単一のスレッドで作成されます。ミューテックス、条件変数、その他のpthreadオブジェクトの状態を含め、親の仮想アドレス空間全体が子に複製されます。pthread_atfork(3)の使用は、これが引き起こす可能性のある問題の処理に役立つ場合があります。


しかし、それは奇妙に思われます:実際のスレッド(仮想メモリ以外の場所にストレージが含まれていることがわかりません)がない場合、forkを呼び出すプロセスのスレッドのスタックがコピーされるのはなぜですか?

まあそれの理由は完全に別の質問です。その実装に至った当初の設計上の決定は知りません。興味がある場合は、別の質問として質問してください。
ケイラム

@dipが他のスレッドのスタックはコピーされません、だれがそう言ったのですか?
Jean-BaptisteYunès

1
@Jean-BaptisteYunèsUNIXシステムには、プロセスの仮想メモリを表す構造体があります。それがコピーされたものです。ヒープとbssだけではない

6
メモリ空間全体、つまりすべてのスレッドのスタックを取得します。残りのスレッドがアクセスできるスタック(またはスタティックメモリ)にあるポインターが指している場所に制限がないため、これが必要です。元のプロセスの一部のスレッドのスタックにあるデータを指している可能性があります
davidbak

4

Open Group Base Specifications Issue 7、2018 Editionのフォークから

プロセスは単一スレッドで作成されます。マルチスレッドプロセスがfork()を呼び出す場合、新しいプロセスには、呼び出しスレッドのレプリカとその全体のアドレス空間が含まれます(ミューテックスやその他のリソースの状態を含む場合があります)。その結果、エラーを回避するために、子プロセスは、execの 1つが実行されるまで、非同期シグナルに対して安全な操作のみを実行できます。関数のが呼び出されるます。

アプリケーションがシグナルハンドラーからfork()を呼び出し、pthread_atfork()によって登録されたフォークハンドラーのいずれかがasync-signal-safeではない関数を呼び出す場合、動作は未定義です。


-2

元々、「フォーク」は、タスクをディスクに書き込んでから、別のスレッドで読み込む(タスクを別のスレッドと交換する場合に行われる)のではなく、メモリ内にあるイメージのタスクIDを変更して続行することで実現されていました。 (新しいタスクとして)その実行で。これは、一度に1つのタスクのみがRAMメモリを占有するという、基本的なタスク切り替えメカニズムに対する非常に単純な変更でした。

もちろん、メモリ管理がより複雑になったため、このスキームは新しい環境に合わせて変更されました。


なぜこれが反対票が投じられたのか興味があります。これがUnixのやり方です。
ホットリック

これは興味深い洞察ですが、スレッドについてはどこに言及していますか?私に対する答えのようには見えません。
wastl
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.