ホームページ  >  記事  >  システムチュートリアル  >  方法論: Linux プロセスの終了方法を理解する

方法論: Linux プロセスの終了方法を理解する

王林
王林転載
2023-12-31 13:27:271284ブラウズ
###導入### プロセスが終了または途中で終了した場合、カーネルはプロセスが占有しているシステム リソースを解放する必要があります。これには、プロセスの実行中に開かれたファイル、要求されたメモリなどが含まれます。 プロセス終了
Linux におけるプロセスの終了は、正常終了と異常終了の 2 種類に分けられます:

1.通常通り終了します

a. main() 関数で return を実行します。

b. exit() 関数を呼び出します

c. _exit() 関数を呼び出す

2.異常終了

a. 関数についての呼び出し

b. プロセスはシグナルを受け取り、そのシグナルによってプログラムが終了します。

どの終了方法が使用されても、システムは最終的にカーネル内で同じコードを実行します。このコードは、プロセスによって使用されている開いているファイル記述子を閉じ、プロセスが占有しているメモリおよびその他のリソースを解放するために使用されます。

いくつかの終了方法の比較

1. 終了と復帰の違い:

exit はパラメータを持つ関数です。 exit が実行された後、制御はシステムに渡されます

return は関数実行後のリターンです。 renturn が実行された後、制御は呼び出し元の関数に渡されます。

2. 終了と中止の違い:

exit はプロセスの正常終了です

aboutは異常終了です。

exit() 関数と _exit() 関数

exit 関数と _exit 関数は両方ともプロセスを終了するために使用されます。プログラムが exit または _exit を実行すると、システムは残りの操作をすべて無条件に停止し、さまざまなデータ構造をクリアして、プロセスの実行を終了します。

exit はヘッダー ファイル stdlib.h で宣言され、_exit() はヘッダー ファイル unistd.h で宣言されます。 exit のパラメータ exit_code が 0 の場合はプロセスが正常に終了したことを意味し、それ以外の値の場合はプログラム実行中にエラーが発生したことを意味します。

exit() と _exit() の違い

_exit() は実行後すぐにカーネルに戻りますが、exit() は最初にいくつかのクリア操作を実行してから、制御をカーネルに移す必要があります。

_exit 関数が呼び出されると、プロセスのすべてのファイル記述子が閉じられ、メモリやその他のカーネル クリーニング関数がクリーンアップされますが、ストリーム (stdin、stdout、stderr...) は更新されません。 function is in _exit _exit を呼び出し、呼び出す前にストリームをフラッシュする関数のラッパー。

exit() 関数と _exit() 関数の最大の違いは、exit() 関数がファイルのオープン ステータスをチェックし、終了システムを呼び出す前にファイル バッファの内容をファイルに書き戻すことです。 Linuxの標準関数ライブラリには「バッファI/O」という動作があるため、開いているファイルごとにメモリ上にバッファが存在するのが特徴です。ファイルが読み取られるたびに、複数のレコードが連続して読み取られるため、次回ファイルを読み取るときは、メモリ バッファから直接読み取ることができます。同様に、ファイルが書き込まれるたびに、メモリに書き込まれるだけです。バッファ。特定の条件が満たされると (特定の数値に達する、または特定の文字に遭遇するなど)、バッファ内の内容が一度にファイルに書き込まれます。このテクノロジはファイルの読み取りと書き込みの速度を大幅に向上させますが、プログラミングには多少の問題も伴います。たとえば、ファイルに書き込まれたと思われるデータがありますが、実際には特定の条件を満たしていないため、バッファに保存されているだけです。このとき、_exit()関数を使用して直接クローズします。プロセスが完了すると、バッファ内のデータが失われます。したがって、データの整合性を確保したい場合は、exit() 関数を使用する必要があります。

関数の例を通してそれらの違いを見てみましょう:

関数例 1: exit.c

リーリー

実行結果は次のとおりです:

リーリー

関数例 2: _exit.c

リーリー

実行結果は次のとおりです:

リーリー

printf 関数はバッファリングされた I/O を使用します。この関数は、「\n」改行文字を検出すると、バッファからレコードを自動的に読み取ります。したがって、exit() はバッファにデータを書き込んだ後に終了しますが、_exit() 関数は直接終了します。

関数インスタンス 2 の printf("これはバッファ内のコンテンツです"); を printf("これはバッファ内のコンテンツです\n") に変更することもできます (つまり、printf の最後に \n を追加します)実行結果は何ですか?なぜそのような結果が得られるのかを確認します)

親プロセスと子プロセスの終了順序が異なると、異なる結果が生じます

1. 親プロセスは子プロセスより前に終了します:

この状況は、以前に使用した孤立プロセスです。親プロセスが最初に終了すると、システムは init プロセスに子プロセスを引き継がせます。

2. 子プロセスは親プロセスより先に終了しますが、親プロセスは wait 関数を呼び出しません

この場合、子プロセスはゾンビ状態になり、システムが再起動されるまでゾンビ状態のままになります。子プロセスがゾンビ状態にある場合、カーネルは親プロセスのプロセスに関する必要な情報のみを保存します。このとき、子プロセスは常にリソースを占有するため、システムが作成できるプロセスの最大数も減少します。

ゾンビ状態とは何ですか?

終了したが、親プロセスがまだ処理 (終了した子プロセスに関する情報を取得し、まだ占有しているリソースを解放) していないプロセスは、ゾンビ プロセス (ゾンビ) と呼ばれます。

3. 子プロセスは親プロセスより先に終了し、親プロセスは wait 関数を呼び出します

この時点で、親プロセスは子プロセスが終了するまで待機します。

以上が方法論: Linux プロセスの終了方法を理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlinuxprobe.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。