[Linuxの基本の紹介](13)Linuxプロセスの概念

1はじめに

コンテンツ

  • Linuxでは、特定のプログラムが応答しないことは避けられません。いくつかのコマンドを使用すると、システムをよりスムーズに実行できます。その前に、Linuxが提供するツールをより良く、より効率的に使用するために、プロセスの基本的な知識をある程度理解する必要があります。

知識のポイント

  • プロセスと手順
  • プロセスの導出
  • 作業管理

2概念の理解

まず第一に、手順とプロセスは何ですか?プログラムとプロセスの違いは何ですか?

手順:正確さ​​を欠くために、手順は、特定の結果を達成するのに役立つ論理的かつ順次的な構造で一連の命令を実行することです。レストランに行って、ウェイターに牛丼が欲しいと言ったときと同じように、牛丼の作り方をして、やっとこんなお椀を手に入れました。それは実行される必要があります、さもなければそれは武道の秘密の本のようです、ただそこにそれを置いて、誰かがそれを通して見るのを待ってください。

プロセス:プロセスは、データセット上でのプログラムの実行プロセスです。初期のUNIX、Linux 2.4以前のバージョンでは、プロセスはシステムリソースの割り当てとスケジューリングのための独立した基本単位でした。前の例と同じように、レストランに行って、ウェイターに牛ごはんのトッピングが欲しいと言ったように、彼女は牛ご飯のトッピングを作る手順を実行し、その中での調理はプロセスであり、牛肉のスープはプロセスでした。、牛肉のスープとご飯を混ぜるのがプロセスで、ご飯をテーブルに置くのがプロセスです。それは、私たちが武道の秘密を見て、それを章ごとに実践しているようなものです。

簡単に言えば、プログラムは、vimがプログラムであるなど、特定のタスクを実行するために設計されたソフトウェアです。プロセスとは何ですか?プロセスは実行中のプログラムです。

プログラムは、一連の命令の単なるコレクションであり、静的エンティティです。プロセスとは異なり、プロセスには次の特徴があります。

  • 動的:プロセスの本質は、作成やキャンセルなどの状態変化を伴うプログラム実行のプロセスです。プログラムは静的エンティティです。
  • 並行性:プロセスでは、一定期間に複数のプログラムを実行できます。プログラムは単なる静的エンティティであるため、並行性はありません。
  • 独立性:プロセスは、リソースを独立して割り当て、スケジューリングを独立して受け取り、独立して実行できます。
  • 非同期:プロセスは予測できない速度で進行します。
  • 構造:プロセスには、コードセグメント、データセグメント、PCB(プロセス制御ブロック、プロセスの存在の唯一の兆候)があります。プロセスが独立して実行できるのは、まさにその構造によるものです。

同時実行性:ある期間に、巨視的なビューでアクティブであり、整然と実行される複数のプログラムがあります(一度に実行されるのは1つだけですが、一定期間に複数のプログラムが実行されました)

並列:常に、同時に実行されている複数のプログラムがあります。これには複数のCPUが必要です。

プロセス自体は操作の基本単位ではなく、スレッドのコンテナーです。各部門がさまざまなワーキンググループ(スレッド)に細分化されるように、ワーキンググループに必要なリソースをより高いレベル(プロセス)に適用する必要があります。

スレッド(スレッド)は、オペレーティングシステムが操作のスケジューリングを実行できる最小単位です。これはプロセスに含まれ、プロセスの実際の操作単位です。スレッドとは、プロセス内の単一の順次制御フローを指します。プロセス内で複数のスレッドを同時に実行でき、各スレッドは異なるタスクを並行して実行します。スレッドにはシステムリソースがほとんど含まれていないため、実行はより高速で効率的です。

つまり、プログラムには少なくとも1つのプロセスがあり、プロセスには少なくとも1つのスレッドがあります。スレッドの分割スケールはプロセスの分割スケールよりも小さいため、マルチスレッドプログラムの同時実行性は高くなります。さらに、プロセスには実行中に独立したメモリユニットがあり、複数のスレッドがメモリを共有するため、プログラムの効率が大幅に向上します。

3プロセス属性

3.1プロセスの分類

プロセスの機能とサービスの目的に応じて、ユーザープロセスとシステムプロセスに分けることができます。

  • ユーザープロセス:ユーザープログラム、アプリケーションプログラム、またはカーネル以外のシステムプログラムを実行することによって生成されるプロセス。このタイプのプロセスは、ユーザーの制御下で実行またはシャットダウンできます。
  • システムプロセス:メモリリソースの割り当てやプロセスの切り替え、その他の比較的低レベルのタスクなど、システムカーネルプログラムの実行によって生成されるプロセス。プロセスの操作はユーザーの介入の対象ではなく、rootユーザーでさえ干渉することはできません。システムプロセスの操作。

アプリケーションのサービスタイプに応じて、インタラクティブプロセス、バッチプロセス、デーモンプロセスに分けることができます。

  • 対話型プロセス:シェル端末によって開始されるプロセス。実行中にユーザーと対話する必要があります。フォアグラウンドまたはバックグラウンドで実行できます。
  • バッチプロセス:このプロセスはプロセスの集合であり、他のプロセスを順番に開始する役割を果たします。
  • デーモン:デーモンは常に実行されるプロセスであり、Linuxシステムが起動すると開始し、システムがシャットダウンすると終了します。これらは制御端末から独立しており、定期的に特定のタスクを実行するか、特定のイベントの処理を待機します。たとえば、httpdプロセスは常に実行されており、ユーザーアクセスを待機しています。頻繁に使用されるcron(centOSシリーズのcrond)プロセスもあります。これは、ユーザーが設定した特定のタスクを定期的に実行できるcrontabのデーモンプロセスです。

3.2プロセスの導出

親プロセスと子プロセスに関しては、これら2つのシステムコールfork()exec()について説明します。

fork()はシステムコールです。その主な機能は、現在のプロセスの新しいプロセスを作成することです。この新しいプロセスはその子プロセスです。この子プロセスは、親プロセスの戻り値とPID以外です。すべてが正確に同じように、プロセスの実行コードセグメント、メモリ情報、ファイルの説明、レジスタステータスなど、fork()は一度に2つの戻り値を呼び出し、子プロセスはゼロを返し、親プロセスはpidを返します子プロセスの。

exec()もシステムコールであり、その役割は、子プロセスで実行プログラムを切り替えること、つまり、親プロセスからコピーされたコードセグメントとデータセグメントを置き換えることです。

子プロセスはシステムコールfork()を介し親プロセスによって生成されたコピーです。Fork()は、親プロセスのPCBおよび他のプロセスのデータ構造情報を直接コピーしますが、PIDを変更するため、まったく同じです。 、exec()を実行する場合のみ、後で異なり、以前のfork()はより多くのリソースを消費し、後ではるかに高いレートのvfork()に進化します。

簡単な実装ロジックは次のとおりです

pid_t p;

p = fork();
if (p == (pid_t) -1)
        /* ERROR */
else if (p == 0)
        /* CHILD */
else
        /* PARENT */

子プロセスが正常に終了するか、プロセスが終了すると、そのメイン関数main()exit(n);を実行するnを返します。ここで、戻り値nはシグナルであり、システムはSIGCHLDシグナルをその親に渡します。もちろん、プロセスが異常終了した場合は、この信号が原因であることがよくあります。

プロセス終了時の子プロセスのコード実行部分は実行を終了し、システムリソースは基本的にシステムに返されますが、プロセスのプロセス制御ブロック(PCB)がまだメモリに存在し、そのPCBがまだそこにあり、プロセスがまだ存在し(PCBがプロセスの唯一の兆候であるため、PIDやその他のメッセージが含まれているため)、プロセスが停止していないことを意味します。このようなプロセスはゾンビプロセス(ゾンビ)と呼ばれます。

通常の状況では、親プロセスは2つの戻り値を受け取ります。終了コード(SIGCHLDシグナル)と終了理由ですその後、親プロセスはwait(&status)システムコールを使用して子プロセスの終了ステータスを取得し、カーネルは終了した子プロセスのPCBをメモリから解放できます。そうしないと、子プロセスのPCBは常にメモリに常駐し、ゾンビプロセス(ゾンビ)としてシステムに残ります。

ゾンビプロセスはほとんどすべてのメモリスペースを放棄し、実行可能コードがなく、スケジュールできませんが、プロセスの終了ステータスと、親プロセスが収集して解放するためのその他の情報を記録するために、プロセスリスト内の位置を予約します。 。ただし、Linuxシステムで使用できるPIDは限られており、システム内にゾンビプロセスが多数ある場合、PIDがないため、システムは新しいプロセスを生成できません。

また、親プロセスが終了(異常終了)した場合、子プロセスは時間内に復旧できず、子プロセスは実行中です。このような子プロセスは孤立プロセスと呼ばれます。Linuxシステムでは、孤立したプロセスは通常、initプロセスによって「採用」され、initの子プロセスになります。余波はinitによって処理され、害はありません。

プロセス0は、システムの起動時に作成される特別なプロセスであり、カーネル初期化とも呼ばれます。最後のアクションは、fork()を呼び出して/ sbin / init実行可能ファイルを実行する子プロセスを作成することです。プロセスは、PID = 1プロセス1です。 、およびプロセス0はスワッププロセス(アイドルプロセスとも呼ばれます)に変換され、プロセス1(initプロセス)は最初のユーザーモードプロセスであり、次にfork()を呼び出してシステム内に他のプロセスを作成し続けます。すべてのプロセスの親または祖先のプロセスです。同時に、それはデーモンであり、コンピューターがシャットダウンされるまで停止しません。

次のコマンドでこの構造をはっきりと見ることができます

pstree

このようなコマンドを使用して、pidがプロセスの一意の番号、ppidがプロセスの親プロセスのpid、およびコマンドがプロセスが実行されるコマンドまたはスクリプトの種類を示すことを確認することもできます。

ps -fxo user,ppid,pid,pgid,command

ここに画像の説明を挿入

3.3プロセスグループとセッション

各プロセスはプロセスグループのメンバーになり、このプロセスグループは一意であり、PGID(プロセスグループID)によって区別され、プロセスが作成されるたびに、その親プロセスがグループのメンバーになります。

一般に、プロセスグループのPGIDは、プロセスグループの最初のメンバーのPIDと同等であり、このようなプロセスは、プロセスグループのリーダー、つまり先頭のプロセスと呼ばれます。プロセスは通常、次のようにしてその場所を見つけます。getpgrp()システムコールの使用グループのPGIDの場合、先頭のプロセスを最初に終了できます。この時点では、プロセスグループはまだ存在し、プロセスグループの最後のプロセスが終了するまで同じPGIDを保持します。

プロセスグループと同様に、プロセスが作成されるたびに、その親プロセスが配置されているセッションのメンバーになります。各プロセスグループはセッション内にあり、このセッションだけが存在します。

セッションは主にttyに対して確立され、セッション内の各プロセスはジョブと呼ばれます。各セッションは端末(制御端末)に接続できます。制御端末に入力と出力がある場合、それらはすべてセッションのフォアグラウンドプロセスグループに渡されます。セッションの意味は、端末に複数のジョブを含め、1つのジョブをフォアグラウンドとして使用して、端末と端末の信号の入出力を直接受信することです。他のジョブはバックグラウンドで実行されます。

フォアグラウンドはターミナルで実行されており、あなたと対話することができます

バックグラウンド(バックグラウンド)はターミナルで実行されていますが、操作したり、実行プロセスを表示したりすることはできません。

3.4作業管理

bash(Bourne-Againシェル)はジョブ制御をサポートしますが、sh(Bourneシェル)はサポートしません。

また、各端末またはbashは、現在の端末のジョブのみを管理でき、他の端末のジョブは管理できません。たとえば、現在2つのbash、つまりbash1とbash2があります。Bash1はそれ自体でジョブを管理することはできますが、bash2のジョブを管理することはできません。

プロセスがフォアグラウンドで動作しているときは、ctrl + c使用してプロセスを終了できますが、バックグラウンドにある場合は機能しません。

記号を使用して、コマンドをバックグラウンドで実行できます

ls &

ここに画像の説明を挿入
[1]図に示す236は、ジョブのジョブ番号とプロセスのPIDであり、最後の行のDoneは、コマンドがバックグラウンドで実行されたことを示します。

ctrl + z使用して、現在のジョブを停止し、バックグラウンドにスローすることもできます。<停止してバックグラウンドに配置されたジョブは、jobsコマンドを使用して表示できます。

jobs

ここに画像の説明を挿入
最初の列はバックグラウンドに配置されたジョブの番号を示し、2番目の列の+は最近(ちょうど今、最後に)バックグラウンドに配置されたジョブを表し、デフォルトのジョブ、つまり、バックグラウンドジョブ操作に何かがある場合、最初はプリセットジョブ用に、-最後から2番目(つまり、プリセットの前のもの)がバックグラウンドに配置され、最後から3番目( before)はそのようなシンボルで装飾されません.3つの列はそれらのステータスを表し、最後の列はプロセスによって実行されたコマンドを表します

このようなコマンドでバックグラウンドワークを前面に出すことができます

#后面不加参数提取预设工作,加参数提取指定工作的编号
#ubuntu 在 zsh 中需要 %,在 bash 中不需要 %
fg [%jobnumber]

ここに画像の説明を挿入
以前は、ctrl + zを使用して、作業がバックグラウンドに配置されないようにしました。バックグラウンドで作業する場合は、このようなコマンドを使用します。

#与fg类似,加参则指定,不加参则取预设
bg [%jobnumber]

ここに画像の説明を挿入

バックグラウンドに配置されたジョブをフォアグラウンドに移動したり、停止からバックグラウンドで実行を継続したりする方法があるため、もちろん、ジョブを削除したり、ジョブを再開したりする方法もあります。

#kill的使用格式如下
kill -signal %jobnumber

#signal从1-64个信号值可以选择,可以这样查看
kill -l

これらの信号値は一般的に使用されます

信号値 効果
-1 再起動と同様に、パラメータを再読み込みして実行します
-2 ctrl + cの操作のように終了します
-9 タスクを強制終了する
-15 通常の方法でタスクを終了します

ここに画像の説明を挿入
注意

  • kill +シグナル値を使用してからpidを直接追加する場合は、pidに対応するプロセスを操作します。
  • kill +シグナル値を使用してから%jobnumberを使用している場合、この時点で操作しているオブジェクトはjobであり、この番号はbashのバックグラウンドで現在実行されているジョブのIDです。

おすすめ

転載: blog.csdn.net/happyjacob/article/details/107045428