1. 序章

Linuxで実行されているプロセスを参照するには、さまざまな方法があります。プロセスごとに異なる識別子があり、そこからプロセスに関する情報を取得できます。

このチュートリアルでは、それらの概念的な定義から始めます。 次に、他の既知の情報から識別子を取得するさまざまな方法に移ります。 出力の意味と、識別子の等しい値または異なる値が意味するものについて説明します。

2. 背景情報

まず、いくつかの基本的な並列コンピューティングの用語を見ていきましょう。  後で見るいくつかの概念を理解するには、この知識が必要です。

プロセスは、メモリスペースやファイル記述子など、特定の目的に割り当てられたリソースのグループです。

スレッドは、スケジューラーによって処理される最も単純なスケジューリング単位です。 言い換えると、スレッドは、プロセッサが操作する命令の最小セットです。

並列プログラミングには、複数の操作を同時に実行して、より高いパフォーマンスを実現する手法が含まれています。 2つの一般的な方法は、マルチスレッドとマルチプロセッシングです。 選択は、計算リソースやソフトウェアアーキテクチャなどの要因によって異なります。

マルチスレッドは、同じプロセス内の複数のスレッドで異なるタスクをスケジュールすることに依存しています。これにより、同じプロセスのスレッドがシステムに割り当てられたメモリリソースを共有します。

マルチプロセッシングは、1つの親プロセスから子プロセスを作成することで構成されます。

プロセスのリソース間の通信は、スレッドの場合ほど単純ではなく、明示的な宣言が必要です。

3. 定義と違い

次に、各識別子の定義を見てみましょう。

3.1. PID プロセス識別子

これは、カーネルでを実行しているすべてのプロセスを識別する一意の番号です。 1から始まり、 systemd (または古いLinuxディストリビューションでは init )に割り当てられます。

3.2。 TID (( スレッド識別子 )。

これは、スレッドを識別するのに役立つ整数です。

シリアルプログラミングでは、スレッドが1つしかないため、TIDとPIDは同じです。

マルチスレッド環境では、各スレッドに独自のTIDがあります。 同じプロセスのすべてのスレッドは同じPIDを持っています。

TIDは常にLWP(軽量プロセス)と同等です。 前者はシステムインターフェイス機能で使用され、後者はユーザー側でより頻繁に使用されます。

プロセス内のスレッドの数はNLWPであり、これはLWPの数を表します。

3.3。 PPID (( 親プロセス識別子 )。

いずれかのプログラムがマルチプロセッシングシーケンスをトリガーすると、多くの子プロセスが作成される親プロセスがあります。 子プロセスには、親プロセスPIDとは異なるPIDがあります。

ただし、すべての子プロセスは同じPPIDを持ちます。これは、親プロセスのPIDと等しく、どの親プロセスから来たかを示します。

4. 既知のプロセス名からPIDを取得する

コマンドpidofに続けて、プロセスの名前を使用できます。

$ pidof firefox
19119 15535 15482 15182 15180 15040 14845 14751 14715 14666

出力には、指定されたプロセス名を持つすべてのPIDが一覧表示されます。

または、アプリケーション名からPID情報を取得するための高度な機能を提供するpgrepというツールがあります。

現在のすべてのシステムプロセスのPIDを取得するには、topなどのコマンドが役立ちます。

5. 既知のPIDからすべてのTIDを取得する

特定のプロセスからPIDがわかれば、PIDで実行されているすべてのスレッドのTIDを取得できます。

この情報にアクセスするには2つの方法があります。 Linuxでは、すべてがファイルです。 ルートディレクトリには、現在実行中のプロセスごとに1つのエントリを含む/proc/というディレクトリがあります。 その中には、プロセス内のスレッドごとに1つのディレクトリを持つ別のディレクトリ task /、があります。

前の例(14715)からPIDを取得して、すべてのTIDを取得してみましょう。

$ ls /proc/14715/task
14715 14719 14720 14723 21345

出力には、PID14715の下にグループ化されたすべてのTIDが表示されます。

前のセクションのpidofの呼び出しに基づいて、Firefoxが複数のスレッドで実行されていることがわかります。 最初のスレッドでは、PIDとTIDは常に一致します。 TIDは常にPID以上になります。

同じ情報を取得する別の方法は、とpsコマンドを使用することです。 コマンドは、 –pid フラグ、 -L フラグ(LWP識別子を取得するため)、およびフラグ-O[を使用して目的のPIDに対して呼び出す必要があります。 X153X]の後に、必要な出力列が続きます。

$ ps --pid 14715 -O tid,lwp,nlwp -L
    PID    TID     LWP  NLWP S TTY          TIME  COMMAND
  14715  14715   14715     5 S   ?      00:00:00  /usr/lib/firefox/firefox
  14715  14719   14719     5 S   ?      00:00:00  /usr/lib/firefox/firefox
  14715  14720   14720     5 S   ?      00:00:00  /usr/lib/firefox/firefox
  14715  14723   14723     5 S   ?      00:00:00  /usr/lib/firefox/firefox
  14715  21345   21345     5 S   ?      00:00:00  /usr/lib/firefox/firefox

以前に取得した同じTIDとは別に、プロセススレッドの総数はNLWP列で取得されます。 出力には、TIDとLWPが同じであることが示されています。

6. 既知のTIDからPIDを取得する

もう1つの一般的なクエリは、既知のTIDからPIDを取得することです。 そのためには、以前と同じコマンドに依存する2つの方法があります。

絶対ディレクトリツールreadlinkを使用して/procディレクトリを探索することにより、特定のTIDのPIDを取得できます。

TID 14719の場合、これは次のようになります。

$ readlink -f /proc/*/task/14719 | cut -d/ -f3
14715

ここで、パイプラインの cut コマンドは、 readlink (TIDのフルパス)の出力を分割し、3番目のスラッシュ(PID)の前の要素を返します。

psをawkと組み合わせて使用して、同じ情報を取得することもできます

以前と同様のフラグ(-Lおよび-O )を、 -e と組み合わせて使用して、すべてを返すことができます。

$ ps -e -O tid -L | awk '$2 == 14719'
  14715  14719   S  ?   00:00:00   /usr/lib/firefox/firefox

ここでは、 psコマンド出力をawkにパイプします。は、2番目の列( $ 2 )が検索しているTIDと等しい行を見つけて返します。

7. 既知のPIDからPPIDを取得する

マルチプロセッシングの場合、PIDからPPIDを取得する方法も2つあります。

対象のPIDの/proc/ディレクトリ内で、ファイルステータスにプロセスに関する情報が含まれています。 grep コマンドを使用して) PPid を検索すると、 PIDプロセスのPPIDを取得できます。

PID 14715を使用した以前のプロセスの場合、PPIDは次のとおりです。

$ cat /proc/14715/status | grep PPid
PPid: 14666

status ファイルで正しい行を見つけるには、検索語PPid大文字化が重要であることに注意してください。

psコマンドで–pid フラグを指定してPIDを指定し、PPID列をoutput として要求することによって( -O ppidを使用して]PPIDを取得することもできます。国旗):

$ ps --pid 14715 -O ppid
    PID   PPID   S  TTY       TIME   COMMAND
  14715  14666   S    ?   00:00:00   /usr/lib/firefox/firefox

8. 既知のPPIDからすべてのPIDを取得する

最後に、PPIDからPIDを取得するために、「ディレクトリ」アプローチはそれほど単純ではないため、1つのソリューションのみを提案します。

psコマンドを使用すると、フラグ–ppid でPPIDを指定することでPIDを取得できます(フラグ -O ppid は、すべてが同じPPIDを持つ必要があることを示すだけです)。

$ ps --ppid 14666 -O ppid
    PID   PPID   S  TTY       TIME   COMMAND
  14715  14666   S    ?   00:00:00   /usr/lib/firefox/firefox
  14751  14666   S    ?   00:00:22   /usr/lib/firefox/firefox
  14845  14666   S    ?   00:04:59   /usr/lib/firefox/firefox
  15040  14666   S    ?   00:42:41   /usr/lib/firefox/firefox
  15180  14666   S    ?   00:08:20   /usr/lib/firefox/firefox
  15182  14666   S    ?   00:01:07   /usr/lib/firefox/firefox
  15482  14666   R    ?   00:15:37   /usr/lib/firefox/firefox
  15535  14666   S    ?   00:06:21   /usr/lib/firefox/firefox
  19119  14666   R    ?   00:01:27   /usr/lib/firefox/firefox

結果から、firefoxは複数のプロセスと複数のスレッドを使用していると言えます。 PID 14666のプロセスは、これらの異なるプロセスを生成します。 したがって、これらのプロセス(14715、14751、14845、…)からのPPIDは14666です。

親プロセスから作成された子プロセスからのPIDは、PPIDよりも大きくなります。 たとえば、PID 14666のプロセスのPPIDを14666にすることはできません(最後のコマンド出力で確認できます)。 これは、PID14666のプロセスがfirefoxの親プロセスであるためです。 システムがこのプロセスを生成したことを考えると、そのPPIDはシステムPIDです。

9. 結論

この記事では、PID、TID、およびPPIDの違いについて説明しました。 適用例を使用して、既知の情報からコマンドを取得するためのさまざまなコマンドと、これらのコマンドの出力の意味について説明しました。