Наложение изображения процесса

Предположим, что мы запускаем программу и хотим запустить другую программу из текущей программы. Это возможно? Почему бы и нет, если реализовать концепцию наложения образа процесса. Это нормально, но как насчет текущей запущенной программы, можно ли ее запустить. Как это возможно, раз уж мы наложили текущую программу на новую. Что делать, если я хочу запустить обе программы без потери текущей запущенной программы, возможно ли это? Да, это возможно.

Создайте дочерний процесс, чтобы у нас были родительский процесс и только что созданный дочерний процесс. Мы уже запускаем текущую программу в родительском процессе, поэтому запустите вновь созданный процесс в дочернем процессе. Таким образом, мы можем запустить другую программу из текущей программы. Не только одну программу, но мы можем запустить любое количество программ из текущей программы, создав такое количество дочерних процессов.

Рассмотрим в качестве примера следующую программу.

/ * Имя файла: 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

Теперь мы запустим следующие две программы из одной программы, то есть execl_run_two_prgms.c.

  • Программа Hello World (helloworld.c)

  • Программа цикла while для печати от 1 до 10 (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;
}

Ниже приведена программа для запуска двух программ (одна программа от дочернего элемента, а другая от родительского).

/ * Имя файла: 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

Теперь мы запустим две программы из одной программы, то есть execl_run_two_prgms.c, ту же программу, что и выше, но с аргументами командной строки. Итак, мы запускаем две программы, а именно helloworld.c в дочернем процессе и программу while_loop.c в родительском процессе. Это выглядит следующим образом -

  • Программа Hello World (helloworld.c)

  • Программа цикла while для печати от 1 до num_times_str в соответствии с аргументами командной строки (while_loop.c)

Эта программа широко выполняет следующие действия -

  • Создает дочерний процесс

  • Дочерний процесс выполняет программу 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;
}

Ниже приведена программа helloworld.c, вызываемая из дочернего процесса программы execl_run_two_prgms.c.

/ * Имя файла: helloworld.c * /

#include<stdio.h>

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

Ниже приводится программа while_loop.c, вызываемая из родительского процесса программы execl_run_two_prgms.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. Если какой-либо аргумент необходимо передать новому образу процесса, он будет отправлен через аргументы «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 []) и другие параметры.