Sobreposição de imagem de processo
Suponha que estamos executando um programa e queremos executar outro programa a partir do programa atual. Isso é possível? Por que não, se implementarmos o conceito de sobreposição da imagem do processo. Tudo bem, mas e o programa em execução no momento, ele também pode ser executado. Como é possível, já que sobrepomos o programa atual com o novo programa. O que fazer, se quiser executar os dois programas sem perder o programa em execução no momento, é possível? Sim, é possível.
Crie um processo filho, para que tenhamos um processo pai e um processo filho recém-criado. Já estamos executando o programa atual no processo pai, então execute o processo recém-criado no filho. Desta forma, podemos executar outro programa a partir do programa atual. Não apenas um único programa, mas podemos executar qualquer número de programas a partir do programa atual, criando esse número de processos filho.
Vamos considerar o seguinte programa como exemplo.
/ * Nome do arquivo: helloworld.c * /
#include<stdio.h>
void main() {
printf("Hello World\n");
return;
}
/ * Nome do arquivo: execl_test.c * /
#include<stdio.h>
#include<unistd.h>
void main() {
execl("./helloworld", "./helloworld", (char *)0);
printf("This wouldn't print\n");
return;
}
O programa acima iria sobrepor a imagem do processo de execl_test com helloworld. Essa é a razão, o código da imagem do processo de execl_test (printf ()) não é executado.
Etapas de compilação e execução
Hello World
Agora, executaremos os dois programas a seguir a partir de um programa, ou seja, execl_run_two_prgms.c.
Programa Hello World (helloworld.c)
Programa de loop while para imprimir de 1 a 10 (while_loop.c)
/ * Nome do arquivo: 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;
}
A seguir está o programa para executar dois programas (um programa do filho e outro programa do pai).
/ * Nome do arquivo: 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 - Faça a chamada sleep () para garantir que os processos filho e pai sejam executados sequencialmente (não sobreponha o resultado).
Etapas de compilação e execução
Child process: Running Hello World Program
This wouldn't print
Parent process: Running While loop Program
Won't reach here
Agora, executaríamos dois programas de um programa, ou seja, execl_run_two_prgms.c, o mesmo programa acima, mas com argumentos de linha de comando. Portanto, estamos executando dois programas, a saber, helloworld.c no processo filho e o programa while_loop.c no processo pai. É o seguinte -
Programa Hello World (helloworld.c)
Programa de loop while para imprimir de 1 a num_times_str de acordo com os argumentos da linha de comando (while_loop.c)
Este programa executa amplamente as seguintes ações -
Cria um processo filho
O processo filho executa o programa helloworld.c
O processo pai executa o programa while_loop.c, passando o valor do argumento da linha de comando como um argumento para o programa. Se os argumentos da linha de comando não forem passados, o padrão será considerado 10. Caso contrário, ele receberá o valor do argumento fornecido. O valor do argumento deve ser numérico; o código não seria validado se fornecido em alfabetos.
/ * Nome do arquivo: 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;
}
A seguir está o programa helloworld.c chamado a partir do processo filho do programa, execl_run_two_prgms.c.
/ * Nome do arquivo: helloworld.c * /
#include<stdio.h>
void main() {
printf("Hello World\n");
return;
}
A seguir está o programa while_loop.c chamado do processo pai do programa, execl_run_two_prgms.c. O argumento para este programa é passado do programa que o executa, isto é, execl_run_two_prgms.c.
/ * Nome do arquivo: 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;
}
Etapas de compilação e execução
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
Vamos agora ver as funções de biblioteca relacionadas com imagens de sobreposição.
#include<unistd.h>
int execl(const char *path, const char *arg, ...);
Esta função sobrepõe a imagem do processo em execução atual com o novo processo, conforme mencionado nos argumentos, caminho e arg. Se algum argumento precisar ser passado para uma nova imagem de processo, isso será enviado por meio de argumentos “arg” e o último argumento deve ser NULL.
Esta função retornaria um valor apenas em caso de erro. As chamadas relacionadas ao processo de sobreposição de imagens são mencionadas abaixo -
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[]);
Essas chamadas abordariam a passagem de argumentos de linha de comando (argv []), variáveis de ambiente (envp []) e outros parâmetros.