プロセスイメージのオーバーレイ
プログラムを実行していて、現在のプログラムから別のプログラムを実行したいとします。これは可能ですか?プロセスイメージをオーバーレイするという概念を実装した場合はどうでしょうか。それは問題ありませんが、現在実行中のプログラムについてはどうでしょうか。それも実行できます。現在のプログラムを新しいプログラムでオーバーレイしたので、どうしてそれが可能ですか。現在実行中のプログラムを失うことなく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;
}
Note − sleep()呼び出しを行って、子プロセスと親プロセスが順番に実行されるようにします(結果と重複しないようにします)。
コンパイルと実行のステップ
Child process: Running Hello World Program
This wouldn't print
Parent process: Running While loop Program
Won't reach here
ここで、1つのプログラムから2つのプログラム、つまりexecl_run_two_prgms.cを実行します。これは、上記と同じプログラムですが、コマンドライン引数を使用します。そのため、子プロセスでhelloworld.c、親プロセスでプログラムwhile_loop.cの2つのプログラムを実行しています。これは次のとおりです-
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 [])、およびその他のパラメーターの受け渡しに対応します。