スレッドが同じPIDを共有している場合、どのようにしてそれらを識別できますか?


97

Linuxでのスレッドの実装に関連するクエリがあります。

Linuxは明示的なスレッドをサポートしていません。ユーザー空間では、スレッドを作成するためにスレッドライブラリ(NPTLなど)を使用する場合があります。NPTLを使用すると、1:1マッピングがサポートされます。

カーネルはこのclone()関数を使用してスレッドを実装します。

4つのスレッドを作成したとします。それからそれはそれを意味するでしょう:

  • 4になりtask_structます。
  • の内部ではtask_struct、クローンを作成するための引数に従って共有リソースのプロビジョニングが行われ(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)ます。

今私は次のクエリを持っています:

  1. 4つのスレッドは同じPIDを持ちますか?誰かが詳しく説明できる場合、PIDがどのように共有されるか。
  2. 異なるスレッドはどのように識別されますか。TID(スレッドID)の概念はありますか?

回答:


272

4つのスレッドは同じPIDを持ちますが、から見た場合のみです。あなた(ユーザーとして)PIDと呼ぶものは、カーネル(下から見て)がPIDと呼ぶものではありません。

では、カーネル、各スレッドは、スレッドのPIDである(それはおそらく、このTID、またはスレッドIDを呼び出すためのより多くの意味になるだろうが)、彼らはまたTGID(スレッドグループID)を持っているPIDと呼ばれるそれ自身のIDを持っていますそれが全体のプロセスを開始しました。

簡単に言うと、新しいプロセスが作成されると、PIDとTGIDの両方が同じ(新しい)番号であるスレッドとして表示されます。

スレッドが別のスレッドを開始するとその開始されたスレッドは独自のPIDを取得します(そのため、スケジューラーは独立してそれをスケジュールできます)が、元のスレッドからTGIDを継承します。

そうすることで、プロセス(スレッドグループID)が報告されている間、カーネルはスレッドが属するプロセスに関係なくスレッドを楽しくスケジュールできます。

以下のスレッドの階層が(a)に役立ちます。

                      USER VIEW
 <-- PID 43 --> <----------------- PID 42 ----------------->
                     +---------+
                     | process |
                    _| pid=42  |_
                  _/ | tgid=42 | \_ (new thread) _
       _ (fork) _/   +---------+                  \
      /                                        +---------+
+---------+                                    | process |
| process |                                    | pid=44  |
| pid=43  |                                    | tgid=42 |
| tgid=43 |                                    +---------+
+---------+
 <-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
                     KERNEL VIEW

新しいプロセス(左側)を開始すると、新しいPID 新しいTGID(どちらも同じ値に設定)が得られますが、新しいスレッド(右側)を開始すると、同じPIDが維持されます。 TGIDを開始したスレッド。


(a) 私の印象的なグラフィックスキルに畏怖の念を覚える:-)


20
FYI、getpid()戻りTGID:asmlinkage long sys_getpid(void) { return current->tgid;}に示すようにwww.makelinux.com/
デューク

6
@デューク-うわー、だから私はgettgid(2)関数を見つけることができませんでした。そして、getpid()TID(スレッドの「PID」)は返されず、どこgettid(2)にあるかがわかります。これにより、メインスレッドにいるかどうかを確認できます。
Tomasz Gandor 2014年

2
これは別の興味深い点につながります。つまり、スレッドとプロセスが(tgidを除いて)カーネル内で同等に処理される場合、マルチスレッドプロセスは結論として、シングルスレッドプロセスよりもCPU時間が長くなります(両方が同じである場合)優先度があり、何らかの理由(mutexの待機など)で停止したスレッドはありません。
アコンカグア2015

1
@ Aconcagua、CFS(Linuxの完全に公平なスケジューラ)は一般にそのように機能しますが、グループスケジューラ拡張を使用して、個々のタスクではなく特定のタスクグループ全体で公平性を機能させることもできます。私は大ざっぱな一見以外にそれを実際に調べたことがありません。
paxdiablo 2015

グループIDを取得する「」のgetpgrp「」
Pengcheng

2

スレッドは、PIDとTGID(スレッドグループID)を使用して識別されます。彼らはまた、どのスレッドが誰の親であるかを知っているので、プロセスは本質的に、プロセスが開始するスレッドとそのPIDを共有します。スレッドIDは通常、スレッドライブラリ自体(pthreadなど)によって管理されます。4つのスレッドが開始される場合、それらは同じPIDを持つ必要があります。カーネル自体がスレッドのスケジューリングなどを処理しますが、ライブラリはスレッドを管理するものです(スレッドの結合および待機メソッドの使用に応じて実行できるかどうか)。

注:これは私のカーネル2.6.36の思い出です。現在のカーネルバージョンでの作業はI / Oレイヤーで行っているため、それ以降変更されたかどうかはわかりません。


-6

Linuxは、fork()システムコールにプロセスを複製する従来の機能を提供します。Linuxには、clone()システムコールを使用してスレッドを作成する機能もあります。ただし、Linuxはプロセスとスレッドを区別しません。

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