プロセス関連の概念
1. プログラムとは何ですか、プロセスとは何ですか?その違いは何ですか?
プログラムは静的な概念です。gcc xxx.c -o pro によって生成された pro ファイルはプログラムと呼ばれます。プロセスはプログラムの実行アクティビティです。プログラムが実行されると、システム内にもう 1 つのプロセスが存在します。各プロセスはpid と呼ばれる、一意の ID を表す負でない整数を持ちます。
pid = 0 swapper process (swapper) 機能: プロセスのスケジューリング
pid = 1 init process 機能: システムの初期化
1. プロセスの作成
1. fork関数を使って作成する
pid_t フォーク(void);
fork 関数が正常に呼び出され、2 回戻ります。
戻り値は 0 で、現在のプロセスが子プロセスであることを意味します。
戻り値は負ではない数値で、現在のプロセスが親プロセスであることを示し、戻り値は子プロセスの ID 番号です。
呼び出しは失敗し、-1 を返します。
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid_t pid2;
pid_t returnpid;
pid = getpid();
printf("befer print:%d\n",pid);
returnpid = fork();
pid2 = getpid();
printf("after print:%d\n",pid2);
if(pid == pid2){
printf("this father print:%d returnpid=%d\n",getpid(),returnpid);
}else{
printf("this child print:%d returnpid=%d\n",getpid(),returnpid);
}
return 0;
}
演算結果
befer pint:8173
after print:8173
this father print:8173 returnpid=8174
after print:8174
this child print:8174 returnpid=0
フォーク前のコードは親プロセスでのみ実行できます。親プロセスと子プロセスはそれぞれ、フォーク後のコードのコピーを持っています。親プロセスと子プロセスは 1 回だけ実行されます。どちらが最初に実行されるかは、スケジュールによって決まります。プロセスの。
2. vfork関数を使用してプロセスを作成します
vfork 作成プロセスとフォークの違い:
1. vfork は、子プロセスが最初に実行されることを保証し、子プロセスが exit を呼び出して終了すると、親プロセスが実行されます。
2.vfork は親プロセスの記憶領域をコピーせずに直接使用するため、親プロセスの変数を子プロセスから変更することができます。
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
main()
{
int cnt = 0;
pid_t pid;
pid_t pid2;
pid = vfork();
if(pid > 0 ){
while(1){
printf("this father print:%d\n",getpid());
sleep(1);
printf("cnt=%d\n",cnt);
}
}else if(pid == 0){
while(1){
printf("this child print:%d\n",getpid());
sleep(1);
cnt++;
if(cnt == 3){
exit(0);
}
}
}
return 0;
実行結果: 親プロセスが実行される前に、子プロセスが終了するのを待ちます (通常の終了を使用します)。子プロセスは、親プロセスの記憶領域を使用して、親プロセス cnt の値を変更します。
this child print:8680
this child print:8680
this child print:8680
this father print:8679
cnt=3
this father print:8679
cnt=3
this father print:8679
cnt=3
this father print:8679
2. プロセス作成の目的
親プロセスは、親プロセスと子プロセスが異なるコード セグメントを同時に実行できるように、自分自身を複製したいと考えています。ネットワーク サーバー プロセスでは、親プロセスはクライアント接続要求を待ちます。要求が到着すると、親プロセスは fork を呼び出し、子プロセスが要求を処理できるようにし、親プロセスは次の要求の到着を待ち続けます。初期段階では、子プロセスのすべてのコードが親プロセスにコピーされ、後の段階では書き込み操作がコピーされます。
3. プロセスの終了
1.通常終了
1.メイン関数呼び出し return
2. プロセスは標準 C ライブラリの exit() を呼び出します。
3. プロセスは、システム コールである _exit() または _Exit() を呼び出します。
補充:
1. プロセスの最後のスレッドが戻ります。
2. 最後のスレッドは pthread_exit を呼び出します
2.異常終了
1. 通話中止
2. プロセスが Ctrl+C などの特定のシグナルを受信したとき
3. 最後のスレッドがキャンセル要求に応答します。
4. 子プロセスが終了するまで待ちます
1. 子プロセスが終了するまで待つ必要はありません。
実行用の子プロセスを作成するとき、子プロセスがどのように実行されているか (作業が完了したかどうか、および完了しない理由) を知りたいと思います。このとき、親プロセスは子プロセスが終了するまで待機する必要があります。子プロセスの終了ステータスを収集します。作業が完了した場合は正常終了し、ステータスコードから作業の実行状況が判断されますが、作業が完了していない場合は異常終了となり、終了ステータスコードに基づいて原因が判断されます。子プロセスの終了ステータスが収集されない場合、子プロセスはゾンビプロセス(ゾンビプロセス)となります。
子プロセスは exit 関数を呼び出し、親プロセスは wait 関数を呼び出して終了ステータス wait(&status) を収集し、次のマクロを使用して結果を解析します。
wait 関数を呼び出して終了ステータスを収集することに加えて、waitpid を使用することもできます。違いは、wait にはユーザーがブロックされるのに対し、waitpid には呼び出し元のブロックを防ぐオプションがあることです。関連する関数プロトタイプは次のとおりです。
status パラメータ: 整数ポインタ
、null 以外: 子プロセスの終了ステータスは、子プロセスが指すアドレスに配置されます。
空: 終了ステータスを気にしません
通常は pid>0 を使用します
通常は WNOHANG を使用します。サスペンド モードはブロックしません。
5. オーファンプロセス
親プロセスが子プロセスの終了を待たない場合、親プロセスは子プロセスよりも先にその「寿命」を終えることになり、このとき子プロセスは孤立プロセスと呼ばれます。
Linux では、システムに孤立プロセスが多すぎるのを防ぎ、init プロセスが孤立プロセスを取り込み、孤立プロセスの親プロセスになります。