GNU/Linux >> Linux の 問題 >  >> Linux

UNIX プロセスの概要 (Linux プロセスの内部とプロセスの種類)

プロセスは、プログラムの実行中のインスタンスです。この記事では、「プログラム」と「実行中のインスタンス」という 2 つの用語を使用しました。プログラムを同時に 5 回実行すると、各インスタンスに対応するプロセスがシステム内で実行されるとします。そのため、プロセスはプログラムの「実行中のインスタンス」であると言えます。

ご存知のように、ps コマンドを使用して、システムで実行中のプロセスを表示できます。 ps コマンドの効果的な使用方法については、プロセス監視のための 7 つの PS コマンドの実用的な例を参照してください。

1.プロセス内部の覗き見

さて、プロセスが正確に何であるかが明確になったので、もう少し深く掘り下げて、プロセスが何で構成されているかを見てみましょう。 Unix プロセスは、以下を含むコンテナと考えることができます:

プログラムの説明

プログラム命令は、CPU によって実行されるテキスト セグメントに保持されます。通常、頻繁に実行されるテキスト エディタのようなプログラムでは、テキスト セグメントが共有されます。このセグメントには読み取り専用権限があり、プログラムはそのテキスト セグメントを変更できません。

データ

ほとんどのデータは、データ セグメントに保持されます。データ セグメントは、初期化されたデータ セグメントと初期化されていないデータ セグメントに分類できます。名前が示すように、初期化されたデータ セグメントには事前に初期化されたグローバル変数が含まれ、初期化されていないデータ セグメント (「BSS」セグメントとも呼ばれる) には初期化されていないグローバル変数が含まれます。また、静的変数はデータ セグメントに格納されます。

関数にローカルなローカル変数はスタックに格納されます。スタックは関数に固有であり、ローカル変数に関する情報を含むだけでなく、関数の実行が完了するとフローが戻るアドレスに関する情報も含まれます。スタックには、一部のマシン レジスタもスタックに格納されているなど、呼び出し元の環境に関する情報も含まれています。呼び出された関数は、ローカル変数とスタック自体の一時変数にメモリを割り当てます。再帰関数の場合、関数呼び出しごとに独立したスタックが存在します。

次に、ヒープに格納されるデータがあります。このデータのこのメモリは、実行時にヒープ セグメントに割り当てられます。ヒープ セグメントはプロセスに対してローカルではなく、プロセス間で共有されます。これが、C プログラマーが、ヒープ セグメントで発生し、システム上の他のプロセスに影響を与える可能性があるメモリ リークを心配する理由です。

コマンドライン引数と環境変数

プロセスには、環境変数と、プログラムに渡すコマンド ライン引数を格納するためのスペースも含まれています。通常、コマンド ライン情報を含むベクトルがここに格納され、この情報ベクトルのアドレスとベクトル内の要素数が 'argv' と 'argc' ('main()' 関数の 2 つの引数) にコピーされます。 /P>

上記の情報に加えて、プロセスには次のような情報も含まれます

  • I/O の状態
  • その優先度とその他の制御情報

プロセスの最も重要な制御情報の 1 つは特権です。プロセスは、このプロセスをトリガーしたユーザーのすべての権限を直接継承します。たとえば、スーパーユーザー権限を持たないユーザーによってトリガーされたプロセスは、ルート権限を必要とすることを実行できませんが、ルートによってトリガーされたプロセスは、プログラムされていることを実行できます。上記の規則の例外は、特定のプロセスに setuid または setgid ビットが設定されている場合に、プロセスがそれをトリガーしたユーザーよりも大きな特権を取得できる場合です。ただし、ここでは詳しく説明しません (詳細については、setuid と setgid のマニュアル ページを参照してください)。

2.バックグラウンド プロセスとフォアグラウンド プロセス

すでに説明したように、Unix ではその名前でプロセスを開始できます。一部の標準プログラムと同様に、「ls」、「ps」などは、シェル プロンプトで名前を入力するだけで起動できます。プロセスを開始するには 2 つの方法があります

  • フォアグラウンドで開始
  • バックグラウンドで開始

時間を消費してカウントを行うユーティリティがあるとします。ユーティリティの名前が「count」だとしましょう。プログラムをフォアグラウンドでトリガーして実行するには、次のコマンドを実行します (「count」は上記のコードのバイナリの名前です):

$ ./count
Counting done

したがって、バイナリ「./count」を実行した後、出力が stdout に表示されるまでに約 10 秒かかり、それまでシェルはこのプロセスだけで占有されていたことがわかります。つまり、同じシェルで他の操作を実行できませんでした。ここで、バックグラウンドでプロセスをトリガーするには、コマンドの最後に「&」を追加します:

$ ./count &
[1] 4120

$ # Do some work on shell while the above program is working in the background

$ Counting done

アンパサンド「&」記号は、このプロセスをバックグラウンド プロセスとして実行する必要があることを示します。バックグラウンド プロセスを実行することで、シェルにアクセスしてその他の操作を実行できます。上記の出力のように、バイナリ「カウント」をバックグラウンドで実行した後、同じシェルでさらにいくつかのコマンドを使用しました。バイナリ「カウント」の処理が完了すると、同じシェルに出力が返されました。 (最後の行)。したがって、デフォルトではすべてのプロセスがフォアグラウンドで実行され、キーボードからの入力 (ある場合) を受け取り、出力をユーザーに返すと結論付けることができます。バックグラウンド プロセスはキーボードから切断されるプロセスであり、ユーザーは同じシェルを使用してより多くの操作を実行できます。

フォアグラウンド プロセスとバックグラウンド プロセスの詳細については、「UNIX バックグラウンド ジョブを管理する方法」を参照してください。

3.プロセスの種類

したがって、プロセスはオペレーティング システムの基本的な概念であることがわかります。 OS 上のほぼすべてのアクティビティは、何らかの処理を行うためのプロセスの形を取ります。システム上で実行されるプロセスにはさまざまな種類があり、そのうちのいくつかは次のとおりです:

子プロセス

実行時に他のプロセスによって作成されるプロセス。通常、子プロセスは、既存のプロセス内からバイナリを実行するために作成されます。子プロセスは fork() システム コールを使用して作成されます。通常、プロセスはシェル/ターミナルを介して実行されます。その場合、シェルが親になり、実行されたプロセスが子プロセスになります。 Unix/Linux では、init プロセスを除く各プロセスに親があります (これについては後で学習します)。

デーモン プロセス

これらは、バックグラウンドで実行される特別なプロセスです。それらは、関連付けられた端末を持たないシステム関連のプロセスです。実行されるこれらのプロセスはルート権限を与え、通常はプロセスにサービスを提供します。デーモン プロセスには端末が接続されていないことが既にわかっているため、これを実現するには、プロセスを端末から切り離す必要があります。 Linux/Unix でこれを行う理想的な方法は、ターミナルを介してプロセスを実行し、このプロセス内から別のプロセスを作成してから、親プロセスを終了することです。親が終了したため、子は端末から独立し、init プロセスによって引き継がれるため、デーモン プロセスになります。典型的な例は、電子メールの到着を待機し、メールの受信時に通知するメール デーモンです。

孤立したプロセス

通常、プロセスは (上記のように) 子プロセスを作成し、子プロセスが終了すると、子プロセスの 1 つが終了したときに必要なすべてのことを親が実行できるように、親プロセスにシグナルが発行されます。しかし、親が殺される状況があります。その場合、子プロセスは孤立し、init プロセスによって引き継がれます。 init プロセスは孤立プロセスの所有権を取得しますが、これらのプロセスは元の親プロセスが存在しないため、孤立プロセスと呼ばれます。

ゾンビ プロセス

子プロセスが終了するか実行を完了すると、親プロセスが終了した子のステータス情報をフェッチするまで、プロセス テーブル内のエントリが残ります。そのため、それまでは終了したプロセスはゾンビ状態になり、ゾンビ プロセスと呼ばれます。プロセスが終了すると、プロセスに関連付けられているすべてのメモリとリソースが解放されますが、プロセス テーブルにはプロセスのエントリが存在します。シグナル SIGCHILD がプロセスの親 (終了したばかり) に送信されます。通常、親のこのシグナルのハンドラーは、終了したプロセスの終了ステータスを取得する「待機」呼び出しを実行し、プロセス テーブルからこのゾンビ プロセスのエントリも削除されます。

4.初期化プロセス

前に説明したように、init プロセスは Linux ブート プロセスの第 6 段階の第 5 段階です。

誰が先に生まれたかという有名な「鶏が先か卵が先か」という理論をご存知でしょう。プロセスに関しては、各プロセスには親プロセスがあるため、親プロセスまたは子プロセスについて同じ質問をすることができます。幸いなことに、ここに答えがあります。その答えは、ブート シーケンス中に最初のプロセスとして開始される init プロセスです。つまり、init プロセスの親は存在しません。 init の PID は「1」なので、ps コマンドを使用して確認します:

したがって、出力から PPID が 0 であることがわかります。これは、このプロセスの親が存在しないことを意味します。

$ ps -l 1
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD
4 S     0     1     0  0  80   0 -  5952 poll_s ?          0:00 /sbin/init

以下は、プロセスを扱うコマンドの一部です:Top コマンド、HTOP コマンド、PS コマンド、Kill (pkill、xkill) コマンド。


Linux
  1. Linuxコマンド-概要と例

  2. Linux – Unixのアクセス許可とファイルタイプを理解していますか?

  3. UNIX / Linux に Alfresco をインストールして構成する 12 の手順

  1. Linux – Unix / linux Osesの標準および/または共通ディレクトリ?

  2. UNIX / Linux:プロセスにシグナルを送信する 3 つの方法

  3. Linux:ゾンビ プロセスを見つけて強制終了する

  1. Linuxでゾンビプロセスを見つけて殺す方法

  2. UNIX / Linux プロセス:C fork() 関数

  3. mmap、msync、および Linux プロセスの終了