Inter-process-communication-process-creation-termination

提供:Dev Guides
移動先:案内検索

プロセスの作成と終了

これまで、プログラムを実行するたびにプロセスが作成され、実行の完了後にプロセスが終了することがわかりました。 プログラム内にプロセスを作成する必要があり、別のタスクをスケジュールする必要がある場合はどうなりますか。 これは達成できますか? はい、明らかにプロセスの作成を通じて。 もちろん、ジョブが完了すると自動的に終了しますが、必要に応じて終了することもできます。

プロセスの作成は、* fork()システムコール*によって実現されます。 新しく作成されたプロセスは子プロセスと呼ばれ、それを開始したプロセス(または実行が開始されたときのプロセス)は親プロセスと呼ばれます。 fork()システムコールの後、親プロセスと子プロセスの2つのプロセスができました。 それらを区別する方法は? 非常に簡単で、戻り値を使用します。

システムコール

子プロセスの作成後、fork()システムコールの詳細を見てみましょう。

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

子プロセスを作成します。 この呼び出しの後、2つのプロセスがあります。既存のプロセスは親プロセスと呼ばれ、新しく作成されたプロセスは子プロセスと呼ばれます。

fork()システムコールは、3つの値のいずれかを返します-

  • エラー、つまり子プロセスの作成に失敗したことを示す負の値。
  • 子プロセスに対してゼロを返します。
  • 親プロセスの正の値を返します。 この値は、新しく作成された子プロセスのプロセスIDです。

簡単なプログラムを考えてみましょう。

File name: basicfork.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
   fork();
   printf("Called fork() system call\n");
   return 0;
}

実行手順

編集

gcc basicfork.c -o basicfork

実行/出力

Called fork() system call
Called fork() system call

注意-通常、fork()呼び出しの後、子プロセスと親プロセスは異なるタスクを実行します。 同じタスクを実行する必要がある場合、fork()呼び出しごとに2乗n回実行されます。ここで、 n はfork()が呼び出される回数です。

上記の場合、fork()は1回呼び出されるため、出力は2回出力されます(2乗1)。 fork()が呼び出された場合、たとえば3回であれば、出力は8回(2乗3)出力されます。 5回呼び出された場合、32回などが出力されます。

fork()が子プロセスを作成したのを見て、今度は親プロセスと子プロセスの詳細を確認します。

ファイル名:pids_after_fork.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
   pid_t pid, mypid, myppid;
   pid = getpid();
   printf("Before fork: Process id is %d\n", pid);
   pid = fork();

   if (pid < 0) {
      perror("fork() failure\n");
      return 1;
   }

  //Child process
   if (pid == 0) {
      printf("This is child process\n");
      mypid = getpid();
      myppid = getppid();
      printf("Process id is %d and PPID is %d\n", mypid, myppid);
   } else {//Parent process
      sleep(2);
      printf("This is parent process\n");
      mypid = getpid();
      myppid = getppid();
      printf("Process id is %d and PPID is %d\n", mypid, myppid);
      printf("Newly created process id or child pid is %d\n", pid);
   }
   return 0;
}

コンパイルおよび実行手順

Before fork: Process id is 166629
This is child process
Process id is 166630 and PPID is 166629
Before fork: Process id is 166629
This is parent process
Process id is 166629 and PPID is 166628
Newly created process id or child pid is 166630

プロセスは、2つの方法のいずれかで終了することができます-

  • 異常に、特定の信号、たとえば終了信号の配信時に発生します。 *通常、_exit()システムコール(または_Exit()システムコール)またはexit()ライブラリ関数を使用します。

_exit()とexit()の違いは、主にクリーンアップアクティビティです。* exit()は、コントロールをカーネルに戻す前に何らかのクリーンアップを行いますが、 _ exit()*(または_Exit())はコントロールをすぐにカーネルに戻します。

exit()を使用した次のプログラム例を検討してください。

ファイル名:atexit_sample.c

#include <stdio.h>
#include <stdlib.h>

void exitfunc() {
   printf("Called cleanup function - exitfunc()\n");
   return;
}

int main() {
   atexit(exitfunc);
   printf("Hello, World!\n");
   exit (0);
}

コンパイルおよび実行手順

Hello, World!
Called cleanup function - exitfunc()

_exit()を使用した次のプログラム例を検討してください。

ファイル名:at_exit_sample.c

#include <stdio.h>
#include <unistd.h>

void exitfunc() {
   printf("Called cleanup function - exitfunc()\n");
   return;
}

int main() {
   atexit(exitfunc);
   printf("Hello, World!\n");
   _exit (0);
}

コンパイルおよび実行手順

Hello, World!