システムでスレッドの実装はどのように行われますか?子プロセスはfork()呼び出しを使用して作成され、スレッドは軽量であることを私は知っています。スレッドの作成は、子プロセスの作成とどのように異なりますか?
4 に答える
スレッドは、clone()
メモリスペースと一部のカーネル制御構造を親と共有する新しいプロセスを作成できるシステムコールを使用して作成されます。これらのプロセスはLWP(軽量プロセス)と呼ばれ、カーネルレベルのスレッドとも呼ばれます。
fork()
最初に親とメモリを共有する新しいプロセスを作成しますが、ページはコピーオンライトです。つまり、元のページのコンテンツが変更されると、個別のメモリページが作成されます。したがって、親プロセスと子プロセスの両方が互いのメモリを変更することはできなくなり、事実上、別々のプロセスとして実行されます。また、新しくフォークされた子は、個別のカーネル制御構造を備えた本格的なプロセスです。
各プロセスには、プロセスがアクセスできる仮想アドレスの範囲とも呼ばれる独自のアドレス空間があります。新しいプロセスがフォークされると、関連するすべてのリソースの複製コピーを作成する必要があります。フォークが完了すると、子と親は独自のアドレススペースとそれに関連するすべてのリソースを持ちます。当然、これはパフォーマンスを重視する操作です。
同じプロセス内のすべてのスレッドは同じアドレス空間を共有しますが、新しいスレッドが生成される場合、各スレッドは独自のスタックのみを必要とし、プロセスの場合のようにすべてのリソースが重複することはありません。したがって、スレッドの生成はパフォーマンスが大幅に低下します。集中的な。
もちろん、2つの操作は、異なる要件に対して本質的に異なる機能を提供するため、比較することはできず、比較すべきではありません。
それは非常に異なります。まず、子プロセスは何らかの方法で親プログラムのコピーであり、すべての変数が複製されています。また、PIDによって子と親が異なります。スレッドは新しいプログラムのようなもので、メインプログラムと同時に実行されます(OSによるCPUのスライス時間のため、同時に実行されるように見えます)。スレッドはプログラムでグローバル変数を使用できますが、プロセスとして重複することはありません。したがって、新しいプロセスよりもスレッドを使用する方がはるかに安価です。
さて、あなたは重要な部分を読みました、今ここにカーテンの後ろに何かがあります:
現在の実装(currentは過去数十年を意味します)では、プロセスメモリはフォークした直後に技術的にコピーされません。もちろん、読み取り専用セクションは、2つのプロセス間で共有されるだけでなく(とにかく変更できないため)、共有ライブラリの読み取り専用部分も共有されます。しかし、最も重要なことは、書き込み可能なものはすべて、最初は共有されるだけです。ただし、これは書き込み保護された方法で共有され、子プロセスメモリに書き込むとすぐに(たとえば、変数をインクリメントすることによって)、カーネルでページフォールトが生成されます。これにより、カーネルは実際にそれぞれのページ(変更が発生する場所)。
「コピーオンライト」と呼ばれるこの優れた最適化により、子プロセスは通常、親プロセスほど(物理的な)メモリを実際には消費しません。ただし、プログラム開発者(およびユーザー)にとっては、完全に透過的です。