Linuxアプリケーションは一般にforkしてからexecve()でexecしますが、Javaアプリケーションと特定のApache MPMはスレッドを使用します。フォークする場合、fork + execを使用してプロセスを生成します。スレッド化の高レベルバージョンは何ですか?JVMまたはワーカーMPMはどのようにしてスレッドを生成しますか?
Linuxアプリケーションは一般にforkしてからexecve()でexecしますが、Javaアプリケーションと特定のApache MPMはスレッドを使用します。フォークする場合、fork + execを使用してプロセスを生成します。スレッド化の高レベルバージョンは何ですか?JVMまたはワーカーMPMはどのようにしてスレッドを生成しますか?
回答:
スレッドとプロセスの背後にある考え方はほぼ同じです。実行パスを分岐します。それ以外の場合、スレッドとプロセスはメモリなどの点で異なります。つまり、スレッドは分割前に存在していたものを共有しながら、プロセスは異なるVMスペースを持っています。
clone()呼び出し(man 2 clone)を使用することによるスレッド化とフォークの両方の基礎となる作業:
fork(2)とは異なり、clone()を使用すると、子プロセスは、その実行コンテキストの一部(メモリ空間、ファイル記述子のテーブル、シグナルハンドラのテーブルなど)を呼び出しプロセスと共有できます。(このマニュアルページでは、「呼び出しプロセス」は通常「親プロセス」に対応することに注意してください。ただし、以下のCLONE_PARENTの説明を参照してください。)
clone()の主な用途はスレッドを実装することです。つまり、共有メモリ空間で同時に実行されるプログラム内の複数の制御スレッドです。
違いは、clone()に渡されるフラグによるものです。manページからわかるように、forkとthreadingはclone()への事前定義されたパラメーターのセットにすぎません。しかし、それを使ってカスタムのものを作ることもできます。
ほとんどの非Unixマルチプロセッシングオペレーティングシステム(OS)は、 "spawn()"コールまたは類似のものを使用して、新しいOSプロセスまたは制御フローを生成します。Spawn()は、非常に複雑な呼び出しになる傾向があり、多くのオプションと多くのオーバーヘッドがあります。Unixの革新の1つは、プロセスを作成するオーバーヘッド方法を大幅に削減することでした-fork()。Unixは、spawn()の残りの半分の前にexec()で任意の量の処理を許可することにより、spawn()に必要な多くのオプションを処理しました。
Unixとそのバリアントがどんどん使用されるようになると、オーバーヘッドの少ないプロセスの作成が有用であることがわかり、使用されました。実際、それはあまりにも多く使用されていたため、プロセスを作成するためのオーバーヘッドの少ない方法が求められていたため、「スレッド」のアイデアが生まれました。もともと、スレッドは元のプロセスによって完全に処理されていました(JVMのようなプログラムはこれを「グリーンスレッド」で行う場合があります)。ただし、マルチスレッドスケジューリングの処理は注意が必要で、頻繁に行われていました。したがって、スレッドを実行する簡単で中間的な方法があります。OSはスケジューリングを処理しますが、(通常)スレッド間でアドレススペースを共有することにより、オーバーヘッドが節約されます。
すべての「スレッド」であるいくつかの異なるが関連する概念があり、詳細については、参照している概念を説明する形容詞が必要であるため、質問に答えるのは困難です。一方、違いを理解することは、おそらくあなたが望む特定の答えに導くでしょう。詳細については、「軽量プロセス」、「ユーザースレッド」、「rfork()」などを検索してください。
CreateProcess()
いませんでしたfork()
。
fork()
ます。
スレッドとフォークは実際には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
pthread
、スレッド実装ではなくAPIです。
JVMとApache MPMはどちらも、ネイティブスレッドをカーネルに依存しています。つまり、OSを使用してスケジュールを設定します。もちろん、どちらも、追跡のために独自のAPIが必要です。
Stackoverflowには、これを扱ういくつかの質問があります。
JVMネイティブスレッド。詳細については、この回答を確認してください。
Apacheには2種類のMPMがあります。スレッドごとに1つのプロセスを持つPreforkと、複数のスレッドを処理するワーカー:Apache MPMです。への参照をチェックしてくださいcodebucket
フォークする場合、fork + execを使用してプロセスを生成します。スレッド化の高レベルバージョンは何ですか?JVMまたはワーカーMPMはどのようにしてスレッドを生成しますか?
これはプラットフォーム固有ですが、Linuxおよび私は、他の多くのPOSIX準拠システムが、ユーザーランドのスレッドAPI であるpthreadsのローカル実装を使用していると想定しています。例えば:
#include <pthread.h>
pthread_t tid;
pthread_create(&tid, NULL, somefunc, NULL);
somefunc
実行の最初のポイントとして新しいスレッド呼び出しを開始します。
スレッドを作成することもできます-フォークとは異なり、スレッドは複製のコピーを取得する代わりに、親プロセスの同じグローバルヒープメモリ空間を共有します(ただし、スレッドはそれぞれ独自の独立したスタックメモリで実行されることに注意してください)-とclone()
の上に構築されているもののpthreadであるシステムコール、。