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

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

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

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

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

  • Во время цикла программа для печати от 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;
}

Примечание. Выполните вызов 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)

  • Во время цикла программа для печати от 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, ...);

Эта функция будет перекрывать текущий запущенный образ процесса новым процессом, как указано в аргументах 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 []) и другим параметрам.