假設我們正在執行一個程式,想從當前程式執行另一個程式。 這可能嗎? 如果我們實現覆蓋進程映像的概念。 當前正在執行的程式呢,也可以執行的。 當前的程式與新程式疊加,如果想執行兩個程式,而不會丟失當前正在執行的程式,有可能嗎?這是可能做到的。
建立一個子進程,以便有一個父進程和一個新建立的子進程。 我們已經在父進程中執行當前程式,所以在子進程中執行新建立的進程。 這樣可以從當前程式執行另一個程式。 不僅是一個程式,而且可以通過建立許多子進程來執行當前程式中的任意數量的程式。
看看以下面的程式範例。檔案: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;
}
上面的程式中,helloworld
程式將覆蓋execl_test
的進程映像。 這就是執行execl_test(printf())
的過程映像程式碼的原因。
編譯和執行的結果如下 -
Hello World
現在,我們將從一個程式執行以下兩個程式,即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;
}
以下是執行兩個程式的程式(一個來自子程式,另一個來自父程式)。
檔案: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
現在從一個程式執行兩個程式,即execl_run_two_prgms.c
,與上面相同的程式,但帶有命令列引數。 所以執行了兩個程式,即子進程中的helloworld.c
和父進程中的while_loop.c
程式。 這是如下 -
1
列印到num_times_str
次數。這個程式大致執行以下操作 -
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, ...);
這個函式會覆蓋當前正在執行的進程映像和引數path
,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 []
)和其他引數。