2016-01-23 17 views
6

Linuxのユーザースペースプロセスでは、どのプロセスがマルチスレッドであるかを簡単に判断できます。あなたはPS -elfを使用しても「スレッド:」に対応するスレッドの数、のためNLWP値を見ることができますは/ proc/$ pidを/ステータスの値。明らかに、LinuxThreadsの日に実装はPOSIX準拠ではありませんでした。しかし、This stackoverflow answerは、 "POSIX.1はスレッドが同じプロセスIDを共有する必要があります。"と言っています。これは明らかにNPTLで修正されています。したがって、NPTLを使用すると、ps -eLfのようなコマンドを使用して、スレッドがすべて同じPIDを共有し、/proc/$ pid/task/の下にあることを確認でき、スレッドに属するすべてのスレッドサブフォルダその "親"プロセス。Linuxカーネルはマルチスレッドを処理しますか?

私はkthreaddによって生成されたカーネルプロセスのための「親」プロセスの下で同様のスレッドグループを見つけることができない、とthis answer下のコメントがあなたは、カーネル空間でPOSIXスレッドを使用することはできません」と言うので、私は実装の違いを疑います素晴らしいスレッドグループはPOSIX機能です。だからps -eLf私は、kthreaddによって作成されたカーネルプロセス(ksoftirqd/0や[nfsd]のように、角括弧を含む)に対して複数のスレッドが表示されることはありません。 (ユーザ空間で使用されている)のpthreadのmanページから

 A single process can contain multiple threads, all of which are 
     executing the same program. These threads share the same global 
     memory (data and heap segments), but each thread has its own stack 
     (automatic variables). 

しかし、これは私が複数のスレッドを含む一つのプロセスの観点では、カーネル「スレッド」のために表示されていない正確に何であります。

要するに、私はkthreaddの子どもたちがなら、私はどんなカーネルプロセスをフォーク/パラレル思ってしまうよりも高いNLWP(スレッド)の値を、持っている「PS」によって記載されたプロセスのいずれかを見ることはありませんユーザー空間プログラムのようなマルチスレッドは(pthreadを使って)行います。実装はどこが違うのですか?

実践例:NFSプロセスのための auxf PSから 出力。デフォルトでは

root   2 0.0 0.0  0  0 ?  S Jan12 0:00 [kthreadd] 
root  1546 0.0 0.0  0  0 ?  S Jan12 0:00 \_ [lockd] 
root  1547 0.0 0.0  0  0 ?  S Jan12 0:00 \_ [nfsd4] 
root  1548 0.0 0.0  0  0 ?  S Jan12 0:00 \_ [nfsd4_callbacks] 
root  1549 0.0 0.0  0  0 ?  S Jan12 2:40 \_ [nfsd] 
root  1550 0.0 0.0  0  0 ?  S Jan12 2:39 \_ [nfsd] 
root  1551 0.0 0.0  0  0 ?  S Jan12 2:40 \_ [nfsd] 
root  1552 0.0 0.0  0  0 ?  S Jan12 2:47 \_ [nfsd] 
root  1553 0.0 0.0  0  0 ?  S Jan12 2:34 \_ [nfsd] 
root  1554 0.0 0.0  0  0 ?  S Jan12 2:39 \_ [nfsd] 
root  1555 0.0 0.0  0  0 ?  S Jan12 2:57 \_ [nfsd] 
root  1556 0.0 0.0  0  0 ?  S Jan12 2:41 \_ [nfsd] 

あなたはそれが8つのプロセスを生成(あるいは、少なくとも彼らは、PIDを持っている)(少なくともinit.dディレクトリサービススクリプト付き)rpc.nfsdサービスを開始するとき。これらのnfsd "プロセス"をフロントエンドとして、カーネルモジュールとして実装されたマルチスレッドバージョンのNFSを作成したいのであれば、1つのPIDでデフォルトの8つの異なるnfsdプロセスをグループ化できなかったのはなぜですか?これとは対照的に、8つの異なるPIDに対して(これは表示されているように - ユーザー空間プロセスとは異なります)?

NSLCDは対照的にマルチスレッドを使用するユーザ空間プログラムの例である:

UID  PID PPID LWP C NLWP STIME TTY   TIME CMD 
nslcd  1424  1 1424 0 6 Jan12 ?  00:00:00 /usr/sbin/nslcd 
nslcd  1424  1 1425 0 6 Jan12 ?  00:00:28 /usr/sbin/nslcd 
nslcd  1424  1 1426 0 6 Jan12 ?  00:00:28 /usr/sbin/nslcd 
nslcd  1424  1 1427 0 6 Jan12 ?  00:00:27 /usr/sbin/nslcd 
nslcd  1424  1 1428 0 6 Jan12 ?  00:00:28 /usr/sbin/nslcd 
nslcd  1424  1 1429 0 6 Jan12 ?  00:00:28 /usr/sbin/nslcd 

PIDが同じであるが、LWP、スレッドごとに一意です。this stackoverflow answerからkthreadd

の機能に

更新:

kthreaddはカーネル空間で実行されるデーモンスレッドです。理由は、 です。カーネルはスレッドを作成する必要がありますが、 カーネルにスレッドを作成することは非常に難しいです。したがって、kthreaddはカーネルが使用するスレッドで、必要に応じて より新しいスレッドを生成します。このスレッドは ユーザー空間のアドレス空間にもアクセスできますが、そうしないでください。その カーネル...

そしてthis oneによって管理:カーネルスレッドデーモン、他のすべての親である デーモンkthreaddの

kthreadd()である主な機能(およびメインループ)カーネルスレッド。

したがって、引用符で囲まれたコードでは、kthreadd デーモンに対する要求が作成されています。この要求を満たすために、kthreaddはそれを読み取り、 カーネルスレッドを開始します。

+3

マルチスレッドは同じリソースをアドレス空間のように共有します。カーネルスレッドはカーネル空間にのみ存在し、__allカーネルスレッドはカーネル空間を自然に共有します。したがって、カーネルマルチスレッドはまったく必要ありません。 –

+0

理解されますが、スレッドはメモリを共有する以上のことを行います。スレッドの全ポイントが並列化されるので、あるスレッドが他のスレッドがスレッドを返すまでブロックまたは待機する必要がなくなり、タスクを新しいスレッドに分割することができます。どのようにしてカーネル内の同じタスクで動作する関連スレッドを追跡することができますか? – SeligkeitIstInGott

+0

私は、別のプロセス/タスクが同じメモリ空間を共有していたが、実際にはpthreadsのmanページと同じプログラムを実行する関連プロセスであることを示す指標としてNLWPを使用していました。これは、タスクをより多くのスレッドに分割することでパフォーマンスが向上するかどうかを確認する場合に、パフォーマンスのチューニングとメトリックにとって重要になります。カーネルは同じ方法で計算タスクを並列化してパフォーマンスを最適化しないのですか?あるいは、「スレッド」は並列化について話す間違ったカテゴリです(pthreadのマニュアルページはそれを関連付けるようです)。 – SeligkeitIstInGott

答えて

7

カーネルにプロセスの概念がないので、あなたの質問は本当に意味をなさない。 Linuxカーネルは、カーネルコンテキストで完全に動作するスレッドを作成できますが、これらのスレッドはすべて同じアドレス空間で実行されます。関連するスレッドには通常関連する名前がありますが、PIDによる類似のスレッドのグループ化はありません。

複数のカーネルスレッドが同じタスクで作業している場合、または他の方法でデータを共有している場合は、ロックまたはその他の並列アルゴリズムを介してそのデータへのアクセスを調整する必要があります。もちろん、pthreads APIはカーネルでは利用できませんが、pthread mutexや条件変数などと同じ機能を利用するために、カーネルのmutexや待ち行列などを使うことができます。

これらのコンテキストを "kernel threads "は、ユーザー空間プロセスの複数のスレッドに非常に類似しているので、かなり良い名前です。それらはすべて(カーネルの)アドレス空間を共有しますが、独自の実行コンテキスト(スタック、プログラムカウンタなど)を持ち、それぞれ独立してスケジュールされ、並列に実行されます。一方、カーネルは、(ユーザー空間のCライブラリの助けを借りて)素敵なPOSIX API抽象化を実際に実装しているため、その実装には完全な抽象化がありません。

+0

非常に有益な答えです。私の困難の1つは用語であり、「プロセス」ではなく「タスク」というカーネルがそれを指定する正しい方法だと言っています。そして、私は質問をフレーム化する方法を知っていて何か難しかったので、私が尋ねようとしていたことを理解してくれてありがとう。そして、2番目のパラグラフは、mutex、待ち行列、私がこの話題について簡単なことを見つけることが難しかったので、基本的にあなたが紹介した方法で言ったことが、印刷物やオンラインには何かありますか? – SeligkeitIstInGott

+0

また、kthreaddが実際に何をしているのかという質問もあります。 kthreaddの子として動作するもの:実際のカーネルスレッドを表示しているのでしょうか、カーネルタスクへの何らかの1:1マッピングを持つユーザースペーススレッドを表示していますか?おそらく彼らの無知のために、私が読んだ記事の中には、PIDを持っているにもかかわらず、実際のカーネルタスクとしてkthreaddの子どもたちを扱っているものがあります。 initプロセスの子供とkthreaddの子供の主な違いは何ですか? – SeligkeitIstInGott

+0

"PIDがあるという事実にもかかわらず" =彼らはプロセスであることを意味します。これはユーザー空間のみの概念であるため、カーネル空間で何が実行されているのかを表すことはできません。 – SeligkeitIstInGott

関連する問題