假設(shè)我們正在運(yùn)行一個(gè)程序,想從當(dāng)前程序運(yùn)行另一個(gè)程序。 這可能嗎? 如果我們實(shí)現(xiàn)覆蓋進(jìn)程映像的概念。 當(dāng)前正在運(yùn)行的程序呢,也可以運(yùn)行的。 當(dāng)前的程序與新程序疊加,如果想運(yùn)行兩個(gè)程序,而不會(huì)丟失當(dāng)前正在運(yùn)行的程序,有可能嗎?這是可能做到的。
創(chuàng)建一個(gè)子進(jìn)程,以便有一個(gè)父進(jìn)程和一個(gè)新創(chuàng)建的子進(jìn)程。 我們已經(jīng)在父進(jìn)程中運(yùn)行當(dāng)前程序,所以在子進(jìn)程中運(yùn)行新創(chuàng)建的進(jìn)程。 這樣可以從當(dāng)前程序運(yùn)行另一個(gè)程序。 不僅是一個(gè)程序,而且可以通過創(chuàng)建許多子進(jìn)程來運(yùn)行當(dāng)前程序中的任意數(shù)量的程序。
看看以下面的程序示例。文件:helloworld.c -
#include<stdio.h>
void main() {
printf("Hello World\n");
return;
}
另一個(gè)文件:execl_test.c -
#include<stdio.h>
#include<unistd.h>
void main() {
execl("./helloworld", "./helloworld", (char *)0);
printf("This wouldn't print\n");
return;
}
上面的程序中,helloworld
程序?qū)⒏采wexecl_test
的進(jìn)程映像。 這就是執(zhí)行execl_test(printf())
的過程映像代碼的原因。
編譯和執(zhí)行的結(jié)果如下 -
Hello World
現(xiàn)在,我們將從一個(gè)程序運(yùn)行以下兩個(gè)程序,即execl_run_two_prgms.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;
}
以下是運(yùn)行兩個(gè)程序的程序(一個(gè)來自子程序,另一個(gè)來自父程序)。
文件: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()
調(diào)用以確保子進(jìn)程和父進(jìn)程順序運(yùn)行(不重疊結(jié)果)。
執(zhí)行上面示例代碼,得到以下結(jié)果 -
Child process: Running Hello World Program
This wouldn't print
Parent process: Running While loop Program
Won't reach here
現(xiàn)在從一個(gè)程序運(yùn)行兩個(gè)程序,即execl_run_two_prgms.c
,與上面相同的程序,但帶有命令行參數(shù)。 所以運(yùn)行了兩個(gè)程序,即子進(jìn)程中的helloworld.c
和父進(jìn)程中的while_loop.c
程序。 這是如下 -
1
打印到num_times_str
次數(shù)。這個(gè)程序大致執(zhí)行以下操作 -
helloworld.c
程序while_loop.c
程序?qū)⒚钚袇?shù)值作為參數(shù)傳遞給程序。 如果命令行參數(shù)沒有被傳遞,那么默認(rèn)值為10
。否則,它取得給定的參數(shù)值。 參數(shù)值應(yīng)該是數(shù)字; 代碼不會(huì)驗(yàn)證。文件: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
程序的子進(jìn)程調(diào)用helloworld.c
程序。
文件:helloworld.c -
#include<stdio.h>
void main() {
printf("Hello World\n");
return;
}
以下是從execl_run_two_prgms.c
程序的父進(jìn)程調(diào)用的while_loop.c
程序。 這個(gè)程序的參數(shù)是從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;
}
執(zhí)行上面示例代碼,得到以下結(jié)果 -
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
現(xiàn)在讓看看覆蓋映像相關(guān)的庫函數(shù)。
#include<unistd.h>
int execl(const char *path, const char *arg, ...);
這個(gè)函數(shù)會(huì)覆蓋當(dāng)前正在運(yùn)行的進(jìn)程映像和參數(shù)path
,arg
中提到的新進(jìn)程。 如果任何參數(shù)需要傳遞給新的進(jìn)程映像,那么將通過“arg”
參數(shù)發(fā)送,最后一個(gè)參數(shù)應(yīng)該是NULL
。
這個(gè)函數(shù)只會(huì)在錯(cuò)誤的情況下返回一個(gè)值。 覆蓋圖像相關(guān)調(diào)用的過程如下所述 -
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[]);
這些調(diào)用將處理傳遞命令行參數(shù)(argv []
),環(huán)境變量(envp []
)和其他參數(shù)。