Inter-process-communication-other-processes

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

その他のプロセス

これまで、プロセス、その作成、親および子プロセスなどについて説明してきました。 孤児プロセス、ゾンビプロセス、デーモンプロセスなど、他の関連プロセスについては説明せずに説明を不完全にします。

孤立プロセス

名前が示すように、孤立は親のないプロセスを意味します。 プログラムまたはアプリケーションを実行すると、アプリケーションの親プロセスはシェルになります。 fork()を使用してプロセスを作成する場合、新しく作成されたプロセスは子プロセスであり、子を作成したプロセスは親プロセスです。 同様に、これの親プロセスはシェルです。 もちろん、すべてのプロセスの親はinitプロセスです(プロセスID→1)。

上記は通常のシナリオですが、親プロセスが子プロセスの前に終了するとどうなりますか。 その結果、子プロセスは孤立プロセスになります。 その親はどうでしょうか。その新しい親はすべてのプロセスの親です。これはinitプロセス(プロセスID – 1)に他なりません。

次の例を使用して、これを試して理解してみましょう。

====/*ファイル名:orphan_process.c */

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

int main() {
   int pid;
   system("ps -f");
   pid = fork();
   if (pid == 0) {
      printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
      sleep(5);
      printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
      system("ps -f");
   } else {
      printf("Parent: pid is %d and ppid is %d\n",getpid(),getppid());
      sleep(2);
      exit(0);
   }
   return 0;
}

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

UID         PID   PPID  C STIME TTY    TIME CMD
4581875  180558      0  0 09:19  ?     00:00:00 sh -c cd/home/cg/root/4581875;
                                       timeout 10s main
4581875  180564 180558  0 09:19  ?     00:00:00 timeout 10s main
4581875  180565 180564  0 09:19  ?     00:00:00 main
4581875  180566 180565  0 09:19  ?     00:00:00 ps -f
Parent: pid is 180565 and ppid is 180564
UID         PID   PPID  C STIME TTY    TIME CMD
4581875  180567      0  0 09:19  ?     00:00:00 main
4581875  180820 180567  0 09:19  ?     00:00:00 ps -f
Child: pid is 180567 and ppid is 180565
Child: pid is 180567 and ppid is 0

ゾンビプロセス

簡単に言えば、2つのプロセス、つまり親プロセスと子プロセスがあると仮定します。 子プロセスを待機してから、プロセステーブルから子プロセスエントリをクリーンアップするのは、親プロセスの責任です。 親プロセスが子プロセスを待機する準備ができておらず、その間に子プロセスがジョブを完了して終了した場合はどうなりますか? これで、子プロセスがゾンビプロセスになります。 もちろん、親プロセスの準備が整うと、ゾンビプロセスはクリーンアップされます。

例の助けを借りてこれを理解しましょう。

====/* ファイル名:zombie_process.c */

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

int main() {
   int pid;
   pid = fork();
   if (pid == 0) {
      system("ps -f");
      printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
      exit(0);
   } else {
      printf("Parent: pid is %d and ppid is %d\n",getpid(),getppid());
      sleep(10);
      system("ps aux|grep Z");
   }
   return 0;
}

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

UID         PID   PPID  C STIME TTY    TIME CMD
4581875  184946      0  0 09:20  ?     00:00:00 sh -c cd/home/cg/root/4581875;
                                       timeout 10s main
4581875  184952 184946  0 09:20  ?     00:00:00 timeout 10s main
4581875  184953 184952  0 09:20  ?     00:00:00 main
4581875  184954 184953  0 09:20  ?     00:00:00 main
4581875  184955 184954  0 09:20  ?     00:00:00 ps -f
Child: pid is 184954 and ppid is 184953

デーモンプロセス

簡単に言えば、関連するシェルや端末を持たないプロセスはデーモンプロセスと呼ばれます。 なぜこれが必要なのですか? これらは、事前定義された間隔でアクションを実行し、特定のイベントに応答するためにバックグラウンドで実行されるプロセスです。 デーモンプロセスは、バックグラウンドプロセスとして実行されるため、ユーザーの操作は必要ありません。

通常、内部Linuxデーモンプロセスは、カーネルデーモン(ksoftirqd、kblockd、kswapdなど)、印刷デーモン(cupsd、lpdなど)、ファイルサービスデーモン(smbd、nmbdなど)などの文字「d」で終了します。 、管理データベースデーモン(ypbind、ypservなど)、電子メールデーモン(sendmail、popd、smtpdなど)、リモートログインおよびコマンド実行デーモン(sshd、in.telnetdなど)、ブートおよび構成デーモン(dhcpd 、udevdなど)、initプロセス(init)、cronデーモン、atdデーモンなど。

デーモンプロセスの作成方法を見てみましょう。 手順は次のとおりです-

  • ステップ1 *-子プロセスを作成します。 これで、親プロセスと子プロセスの2つのプロセスができました。

通常、プロセス階層は、シェル→親プロセス→子プロセスです。

  • ステップ2 *-終了して親プロセスを終了します。 子プロセスは孤立プロセスになり、initプロセスに引き継がれます。

現在、階層はINIT PROCESS→CHILD PROCESSです

  • ステップ3 *-呼び出しプロセスがプロセスグループリーダーでない場合、setsid()システムコールを呼び出すと、新しいセッションが作成されます。 これで、呼び出しプロセスが新しいセッションのグループリーダーになります。 このプロセスは、この新しいプロセスグループとこの新しいセッションの唯一のプロセスになります。
  • ステップ4 *-プロセスグループIDとセッションIDを呼び出しプロセスのPIDに設定します。
  • ステップ5 *-端末とシェルがアプリケーションから切断されたため、プロセスのデフォルトのファイル記述子(標準入力、標準出力、標準エラー)を閉じます。

====/*ファイル名:daemon_test.c */

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char* argv[]) {
   pid_t pid;
   int counter;
   int fd;
   int max_iterations;
   char buffer[100];
   if (argc < 2)
   max_iterations = 5;
   else {
      max_iterations = atoi(argv[1]);
      if ( (max_iterations <= 0) || (max_iterations > 20) )
      max_iterations = 10;
   }
   pid = fork();

  //Unable to create child process
   if (pid < 0) {
      perror("fork error\n");
      exit(1);
   }

  //Child process
   if (pid == 0) {
      fd = open("/tmp/DAEMON.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
      if (fd == -1) {
         perror("daemon txt file open error\n");
         return 1;
      }
      printf("Child: pid is %d and ppid is %d\n", getpid(), getppid());
      printf("\nChild process before becoming session leader\n");
      sprintf(buffer, "ps -ef|grep %s", argv[0]);
      system(buffer);
      setsid();
      printf("\nChild process after becoming session leader\n");
      sprintf(buffer, "ps -ef|grep %s", argv[0]);
      system(buffer);
      close(STDIN_FILENO);
      close(STDOUT_FILENO);
      close(STDERR_FILENO);
   } else {
      printf("Parent: pid is %d and ppid is %d\n", getpid(), getppid());
      printf("Parent: Exiting\n");
      exit(0);
   }

  //Executing max_iteration times
   for (counter = 0; counter < max_iterations; counter++) {
      sprintf(buffer, "Daemon process: pid is %d and ppid is %d\n", getpid(), getppid());
      write(fd, buffer, strlen(buffer));
      sleep(2);
   }
   strcpy(buffer, "Done\n");
   write(fd, buffer, strlen(buffer));

  //Can't print this as file descriptors are already closed
   printf("DoneDone\n");
   close(fd);
   return 0;
}
Parent: pid is 193524 and ppid is 193523
Parent: Exiting
4581875  193525      0  0 09:23  ?      00:00:00 main
4581875  193526 193525  0 09:23  ?      00:00:00 sh -c ps -ef|grep main
4581875  193528 193526  0 09:23  ?      00:00:00 grep main
4581875  193525      0  0 09:23  ?      00:00:00 main
4581875  193529 193525  0 09:23  ?      00:00:00 sh -c ps -ef|grep main
4581875  193531 193529  0 09:23  ?      00:00:00 grep main