Sovrapposizione dell'immagine di processo

Supponiamo che stiamo eseguendo un programma e vogliamo eseguire un altro programma dal programma corrente. È possibile? Perché no, se implementiamo il concetto di sovrapposizione dell'immagine di processo. Va bene, ma per quanto riguarda l'attuale programma in esecuzione, può essere eseguito anche quello. Com'è possibile, visto che abbiamo sovrapposto il programma corrente al nuovo programma. Cosa fare, se voglio eseguire i due programmi senza perdere il programma in esecuzione, è possibile? Sì, è possibile.

Creare un processo figlio, in modo da avere un processo padre e un processo figlio appena creato. Stiamo già eseguendo il programma corrente nel processo genitore, quindi esegui il processo appena creato nel processo figlio. In questo modo, possiamo eseguire un altro programma dal programma corrente. Non solo un singolo programma, ma possiamo eseguire un numero qualsiasi di programmi dal programma corrente creando quel numero di processi figlio.

Consideriamo il seguente programma come esempio.

/ * Nome file: helloworld.c * /

#include<stdio.h>

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

/ * Nome file: execl_test.c * /

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

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

Il programma sopra sovrascriverà l'immagine di processo di execl_test con helloworld. Questo è il motivo per cui il codice dell'immagine di processo di execl_test (printf ()) non viene eseguito.

Fasi di compilazione ed esecuzione

Hello World

Ora, eseguiremo i seguenti due programmi da un programma, cioè, execl_run_two_prgms.c.

  • Programma Hello World (helloworld.c)

  • Programma ciclo while per stampare da 1 a 10 (while_loop.c)

/ * Nome file: 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;
}

Di seguito è riportato il programma per eseguire due programmi (un programma da bambino e un altro programma da genitore).

/ * Nome file: 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 - Posiziona la chiamata sleep () per assicurarti che i processi figlio e genitore vengano eseguiti in sequenza (non sovrapporre il risultato).

Fasi di compilazione ed esecuzione

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

Ora dovremmo eseguire due programmi da un programma, cioè, execl_run_two_prgms.c, lo stesso programma come sopra ma con argomenti della riga di comando. Quindi, stiamo eseguendo due programmi e cioè helloworld.c nel processo figlio e il programma while_loop.c nel processo genitore. Questo è il seguente:

  • Programma Hello World (helloworld.c)

  • Programma ciclo while per stampare da 1 a num_times_str secondo gli argomenti della riga di comando (while_loop.c)

Questo programma esegue in generale le seguenti azioni:

  • Crea un processo figlio

  • Il processo figlio esegue il programma helloworld.c

  • Il processo padre esegue il programma while_loop.c passando il valore dell'argomento della riga di comando come argomento al programma. Se gli argomenti della riga di comando non vengono passati, il valore predefinito è 10. Altrimenti, accetta il valore dell'argomento specificato. Il valore dell'argomento dovrebbe essere numerico; il codice non verrebbe convalidato se fornito in alfabeti.

/ * Nome file: 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;
}

Di seguito è riportato il programma helloworld.c chiamato dal processo figlio del programma, execl_run_two_prgms.c.

/ * Nome file: helloworld.c * /

#include<stdio.h>

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

Di seguito è riportato il programma while_loop.c chiamato dal processo padre del programma, execl_run_two_prgms.c. L'argomento di questo programma viene passato dal programma che lo esegue, ovvero execl_run_two_prgms.c.

/ * Nome file: 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;
}

Fasi di compilazione ed esecuzione

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

Vediamo ora le funzioni di libreria relative alle immagini sovrapposte.

#include<unistd.h>

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

Questa funzione si sovrappone all'immagine del processo in esecuzione corrente con il nuovo processo come menzionato negli argomenti, nel percorso e nell'argomento. Se un argomento deve essere passato a una nuova immagine di processo, verrà inviato tramite argomenti "arg" e l'ultimo argomento dovrebbe essere NULL.

Questa funzione restituirà un valore solo in caso di errore. Il processo di sovrapposizione delle chiamate relative all'immagine è indicato di seguito:

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[]);

Queste chiamate riguardano il passaggio di argomenti della riga di comando (argv []), variabili di ambiente (envp []) e altri parametri.