スレッドと(フォークされた)プロセス


9

Linuxアプリケーションは一般にforkしてからexecve()でexecしますが、Javaアプリケーションと特定のApache MPMはスレッドを使用します。フォークする場合、fork + execを使用してプロセスを生成します。スレッド化の高レベルバージョンは何ですか?JVMまたはワーカーMPMはどのようにしてスレッドを生成しますか?


2
Stackoverflowを確認してください。これの一部を説明したいくつかのQ&Aがあります。
Henk Langeveld

回答:


13

スレッドとプロセスの背後にある考え方はほぼ同じです。実行パスを分岐します。それ以外の場合、スレッドとプロセスはメモリなどの点で異なります。つまり、スレッドは分割前に存在していたものを共有しながら、プロセスは異なるVMスペースを持っています。

clone()呼び出し(man 2 clone)を使用することによるスレッド化とフォークの両方の基礎となる作業:

fork(2)とは異なり、clone()を使用すると、子プロセスは、その実行コンテキストの一部(メモリ空間、ファイル記述子のテーブル、シグナルハンドラのテーブルなど)を呼び出しプロセスと共有できます。(このマニュアルページでは、「呼び出しプロセス」は通常「親プロセス」に対応することに注意してください。ただし、以下のCLONE_PARENTの説明を参照してください。)

clone()の主な用途はスレッドを実装することです。つまり、共有メモリ空間で同時に実行されるプログラム内の複数の制御スレッドです。

違いは、clone()に渡されるフラグによるものです。manページからわかるように、forkとthreadingはclone()への事前定義されたパラメーターのセットにすぎません。しかし、それを使ってカスタムのものを作ることもできます。


1
えっ?何?プロセスのための別個のメモリ空間は一種の大したものであるので、トピックに関するほぼすべての本をもう一度読んでください。クラッシュするコードを「キャッチ」するのにも役立ちますが、カーネルは、個々のスレッドがヘイワイヤー/トレスパスするプロセスを強制終了します。
0xC0000022L 2014

3
@ 0xC0000022Lあなたの議論は私には思えるように、答えと矛盾しません。
ルスラン2014

1
@ルスラン:私は違うことを頼みました:「アイデア[...]はほぼ同じです」?スレッドの背後にあるアイデアは確かに同時実行性ですが、プロセスの場合、これはまったく別の話です。
0xC0000022L 2014

4
@ 0xC0000022L V13の回答の重要な部分を逃しました:「実行パスをフォークしました」-質問は、スレッドとプロセスの違いではなく、スレッドの生成方法に関するものです
イズカタ

@Izkata:全然。これは正しい主張ではないと私は思います。
0xC0000022L 2014

8

ほとんどの非Unixマルチプロセッシングオペレーティングシステム(OS)は、 "spawn()"コールまたは類似のものを使用して、新しいOSプロセスまたは制御フローを生成します。Spawn()は、非常に複雑な呼び出しになる傾向があり、多くのオプションと多くのオーバーヘッドがあります。Unixの革新の1つは、プロセスを作成するオーバーヘッド方法を大幅に削減することでした-fork()。Unixは、spawn()の残りの半分の前にexec()で任意の量の処理を許可することにより、spawn()に必要な多くのオプションを処理しました。

Unixとそのバリアントがどんどん使用されるようになると、オーバーヘッドの少ないプロセスの作成が有用であることがわかり、使用されました。実際、それはあまりにも多く使用されていたため、プロセスを作成するためのオーバーヘッドの少ない方法が求められていたため、「スレッド」のアイデアが生まれました。もともと、スレッドは元のプロセスによって完全に処理されていました(JVMのようなプログラムはこれを「グリーンスレッド」で行う場合があります)。ただし、マルチスレッドスケジューリングの処理は注意が必要で、頻繁に行われていました。したがって、スレッドを実行する簡単で中間的な方法があります。OSはスケジューリングを処理しますが、(通常)スレッド間でアドレススペースを共有することにより、オーバーヘッドが節約されます。

すべての「スレッド」であるいくつかの異なるが関連する概念があり、詳細については、参照している概念を説明する形容詞が必要であるため、質問に答えるのは困難です。一方、違いを理解することは、おそらくあなたが望む特定の答えに導くでしょう。詳細については、「軽量プロセス」、「ユーザースレッド」、「rfork()」などを検索してください。


1
「マルチスレッドスケジューリングの処理は注意が必要で、頻繁に正しく行われていませんでした」引用が必要 ユーザー空間スレッドの実装は問題ではありません。ユーザー空間スレッドの問題は、スレッドがブロッキングシスコールを実行するとすべてのスレッドがブロックされることです。これを回避する唯一の方法は、システムレベルのスレッドを使用することです。
バクリウ2014

1
興味深いことに、WindowsにはこのUnixの革新は含まれてCreateProcess()いませんでしたfork()
ルスラン2014

2
@Bakuriu-マルチプロセッシングスケジューラの構築、公平性の維持、飢餓の回避、優先度の処理などに関する多くの記事を検索します。ユーザー空間のスレッドを実装することは、問題と言えますがそうではありません。重要な例をスケジュールすることは困難です。
mpez0

@Ruslan:Windowsではフォークできますが、Win32 APIの一部ではありません。Nebbettによる「Windows NT / 2000 Native API」を読んでください。彼は模倣する実装をしていfork()ます。
0xC0000022L 2014

3

スレッドとフォークは実際には2つの異なる概念であり、どちらもUnix / Linuxシステムに存在します(両方ともC / C ++で使用できます)。

fork()のアイデアは、(非常に基本的に)親プロセスと同じ実行コードを持ち、fork行で実行を開始する別のプロセスを作成することです。exec関数でforkを使用する目的は、exec関数が終了時にそれらを呼び出したプロセスを閉じることです。したがって、通常はフォークして、各プロセスのPIDを取得し(子は常に0です)、子がexec関数の実行を完了するまで親を待機させます。

スレッドは並列処理に使用されます(親が子で待機することを思い出してください(通常、分岐したプログラムで))。C / C ++のpthread(Google検索を実行)などのスレッドは、メインプロセスと並行して実行され、元のプログラムとグローバル変数およびグローバル関数を共有できます。Javaスレッドは同様に動作するので、フォークプロセスのように動作するのではなく、これらのスレッドのように動作すると思います。

基本的に、フォークとスレッド化には違いがあります。それらは明確に異なることを行います(似ているように見えます)。これらの概念は理解するのが難しい場合がありますが、理解したいという正直な欲求があれば、(広範な)調査を通じてそれらを学ぶことができます。

編集#1

フォークとスレッドを呼び出して使用する方法の例をご覧ください。exec関数の動作とメインプログラムへの影響に注意してください。

http://www.jdembrun.com:4352/computerScience/forkVSthread.zip


2
フォーク(execありまたはなし)は並列処理にも使用できます。「exec関数は、終了時にそれらを呼び出したプロセスを閉じる」という意味がわかりません。execは、プロセスが終了したときに、実行が完了するまで長く実行されます。またpthread、スレッド実装ではなくAPIです。
マット2014

フォークに関しては、私は私のOSの先生を引用しています。彼が私たちに言ったことによると、はい、フォークは並行して実行するために使用できますが、exec関数を使用した場合、それは最後のものになります。pthreadについては、例としてのものです。
jaredad7

Execは、呼び出し元のコードの最後の呼び出しであり、フォークされたプロセスの最後の命令ではありません。フォークされたプロセスは、execされたコードを実行し続けます。
マット2014

あなたのコメントは私にこれらのものをテストするように促しました。exec関数の動作と、フォークとスレッドで使用した場合のプログラムへの影響を示すc ++プログラムをいくつか作成しました。上記の編集をご覧ください。
jaredad7

ほとんどの人はそれをダウンロードする気にしないでしょう。また、例ではモデル間の興味深い違いを示していません。これらは主にアドレス空間の共有(または共有)に関連しています。
2014

1

JVMとApache MPMはどちらも、ネイティブスレッドをカーネルに依存しています。つまり、OSを使用してスケジュールを設定します。もちろん、どちらも、追跡のために独自のAPIが必要です。

Stackoverflowには、これを扱ういくつかの質問があります。

  1. JVMネイティブスレッド。詳細については、この回答を確認してください。

  2. Apacheには2種類のMPMがあります。スレッドごとに1つのプロセスを持つPreforkと、複数のスレッドを処理するワーカー:Apache MPMです。への参照をチェックしてくださいcodebucket


1

フォークする場合、fork + execを使用してプロセスを生成します。スレッド化の高レベルバージョンは何ですか?JVMまたはワーカーMPMはどのようにしてスレッドを生成しますか?

これはプラットフォーム固有ですが、Linuxおよび私は、他の多くのPOSIX準拠システムが、ユーザーランドのスレッドAPI であるpthreadsのローカル実装を使用していると想定しています。例えば:

#include <pthread.h>

pthread_t tid;
pthread_create(&tid, NULL, somefunc, NULL);

somefunc実行の最初のポイントとして新しいスレッド呼び出しを開始します。

スレッドを作成することもできます-フォークとは異なり、スレッドは複製のコピーを取得する代わりに、親プロセスの同じグローバルヒープメモリ空間を共有します(ただし、スレッドはそれぞれ独自の独立したスタックメモリで実行されることに注意してください)-とclone()の上に構築されているもののpthreadであるシステムコール、。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.