Inter-process-communication-overlaying-process-image

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

オーバーレイプロセスイメージ

プログラムを実行しており、現在のプログラムから別のプログラムを実行するとします。 これは可能ですか? プロセスイメージをオーバーレイするという概念を実装するのであれば、どうしてですか。 それは問題ありませんが、現在実行中のプログラムについてはどうでしょうか。 現在のプログラムを新しいプログラムでオーバーレイしたため、どのように可能ですか。 現在実行中のプログラムを失うことなく2つのプログラムを実行したい場合、どうすればよいですか? はい、可能です。

子プロセスを作成して、親プロセスと新しく作成された子プロセスを作成します。 すでに親プロセスで現在のプログラムを実行しているので、子で新しく作成されたプロセスを実行します。 このようにして、現在のプログラムから別のプログラムを実行できます。 単一のプログラムだけでなく、その数の子プロセスを作成することにより、現在のプログラムから任意の数のプログラムを実行できます。

次のプログラムを例として考えてみましょう。

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

#include<stdio.h>

void main() {
   printf("Hello World\n");
   return;
}

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

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

void main() {
   execl("./helloworld", "./helloworld", (char* )0);
   printf("This wouldn't print\n");
   return;
}

上記のプログラムは、execl_testのプロセスイメージをhelloworldでオーバーレイします。 そのため、execl_test(printf())のプロセスイメージコードは実行されません。

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

Hello World

ここで、1つのプログラム(execl_run_two_prgms.c)から次の2つのプログラムを実行します。

  • Hello Worldプログラム(helloworld.c) *1から10まで印刷するwhileループプログラム(while_loop.c)

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

/*Prints numbers from 1 to 10 using while loop*/
#include<stdio.h>

void main() {
   int value = 1;
   while (value <= 10) {
      printf("%d\t", value);
      value++;
   }
   printf("\n");
   return;
}

以下は、2つのプログラム(1つのプログラムは子から、もう1つのプログラムは親から)を実行するプログラムです。

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

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

void main() {
   int pid;
   pid = fork();

  /*Child process*/
   if (pid == 0) {
      printf("Child process: Running Hello World Program\n");
      execl("./helloworld", "./helloworld", (char *)0);
      printf("This wouldn't print\n");
   } else {/*Parent process*/
      sleep(3);
      printf("Parent process: Running While loop Program\n");
      execl("./while_loop", "./while_loop", (char *)0);
      printf("Won't reach here\n");
   }
   return;
}

-sleep()呼び出しを配置し​​て、子プロセスと親プロセスが順番に実行されるようにします(結果と重複しないようにします)。

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

Child process: Running Hello World Program
This wouldn't print
Parent process: Running While loop Program
Won't reach here

ここで、1つのプログラム(execl_run_two_prgms.c)から2つのプログラムを実行します。上記と同じプログラムですが、コマンドライン引数を使用します。 そのため、2つのプログラム、つまり子プロセスのhelloworld.cと、親プロセスのwhile_loop.cプログラムを実行しています。 これは次のとおりです-

  • Hello Worldプログラム(helloworld.c)
  • コマンドライン引数(while_loop.c)に従って1からnum_times_strに出力するwhileループプログラム

このプログラムは、広く次のアクションを実行します-

  • 子プロセスを作成します
  • 子プロセスはhelloworld.cプログラムを実行します *親プロセスはwhile_loop.cプログラムを実行し、コマンドライン引数の値を引数としてプログラムに渡します。 コマンドライン引数が渡されない場合、デフォルトは10とみなされます。 それ以外の場合は、指定された引数値を取ります。 引数値は数値でなければなりません。コードは、アルファベットで指定されている場合は検証されません。

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

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

void main(int argc, char* argv[0]) {
   int pid;
   int err;
   int num_times;
   char num_times_str[5];

  /*In no command line arguments are passed, then loop maximum count taken as 10*/
   if (argc == 1) {
      printf("Taken loop maximum as 10\n");
      num_times = 10;
      sprintf(num_times_str, "%d", num_times);
   } else {
      strcpy(num_times_str, argv[1]);
      printf("num_times_str is %s\n", num_times_str);
      pid = fork();
   }

  /*Child process*/
   if (pid == 0) {
      printf("Child process: Running Hello World Program\n");
      err = execl("./helloworld", "./helloworld", (char *)0);
      printf("Error %d\n", err);
      perror("Execl error: ");
      printf("This wouldn't print\n");
   } else {/*Parent process*/
      sleep(3);
      printf("Parent process: Running While loop Program\n");
      execl("./while_loop", "./while_loop", (char *)num_times_str, (char *)0);
      printf("Won't reach here\n");
   }
   return;
}

以下は、プログラムの子プロセスexecl_run_two_prgms.cから呼び出されるhelloworld.cプログラムです。

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

#include<stdio.h>

void main() {
   printf("Hello World\n");
   return;
}

以下は、プログラムの親プロセスexecl_run_two_prgms.cから呼び出されるwhile_loop.cプログラムです。 このプログラムの引数は、これを実行するプログラム、つまりexecl_run_two_prgms.cから渡されます。

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

#include<stdio.h>

void main(int argc, char* argv[]) {
   int start_value = 1;
   int end_value;
   if (argc == 1)
   end_value = 10;
   else
   end_value = atoi(argv[1]);
   printf("Argv[1] is %s\n", argv[1]);
   while (start_value <= end_value) {
      printf("%d\t", start_value);
      start_value++;
   }
   printf("\n");
   return;
}

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

Taken loop maximum as 10
num_times_str is 10
Child process: Running Hello World Program
Hello World
Parent process: Running While loop Program
Argv[1] is 10
1 2 3 4 5 6 7 8 9 10
Taken loop maximum as 15
num_times_str is 15
Child process: Running Hello World Program
Hello World
Parent process: Running While loop Program
Argv[1] is 15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

ライブラリ関数に関連するオーバーレイ画像を見てみましょう。

#include<unistd.h>

int execl(const char *path, const char *arg, ...);

この関数は、引数、パス、および引数で説明されているように、現在実行中のプロセスイメージを新しいプロセスでオーバーレイします。 引数を新しいプロセスイメージに渡す必要がある場合、「arg」引数を介して送信され、最後の引数はNULLになります。

この関数は、エラーが発生した場合にのみ値を返します。 画像関連の呼び出しをオーバーレイするプロセスは以下のとおりです-

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char *const envp[]);
int execv(const char* path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);

これらの呼び出しは、コマンドライン引数(argv [])、環境変数(envp [])およびその他のパラメーターの受け渡しに対処します。