Вилка и Execlp - PullRequest
       18

Вилка и Execlp

6 голосов
/ 23 августа 2011

Я пытаюсь запустить программу с помощью fork и execlp, в которой родительское адресное пространство заменяется командой "ls".

#include<stdio.h>
main()
{
    int pid,j=10,fd;
    pid=fork();
    if(pid==0)
    {
        printf("\nI am the child\n");
        execlp("/bin/ls","ls",NULL);
        printf("\nStill I am the child\n");

    }
    else if (pid > 0)
    {
        printf("\n I am the parent\n");
        wait();
    } 
}

Когда я выполняю программу, последняя строка дочернего элемента

printf("\nStill I am the child\n");

не печатается.Почему?

Ответы [ 5 ]

16 голосов
/ 23 августа 2011

exec семейные функции не возвращаются в случае успеха.

http://pubs.opengroup.org/onlinepubs/009604499/functions/exec.html

Семейство функций exec должно заменить текущий образ процесса новым образом процесса. Новое изображение должно быть построено из обычного исполняемого файла, называемого новым файлом образа процесса. От успешного выполнения не должно быть возврата, поскольку образ вызывающего процесса перекрывается новым образом процесса.

Если одна из функций exec возвращается к образу вызывающего процесса, произошла ошибка; возвращаемое значение должно быть -1, а errno должно быть установлено для указания ошибки.

4 голосов
/ 23 августа 2011

exec функции не просто выполнят вашу команду.Они на самом деле заменят контекст выполнения процесса выбранным вами исполняемым файлом (в вашем случае /bin/ls).

Другими словами, поскольку функция ls завершается завершением своего процесса (через 'exit' иливозвращая основную функцию или что-либо еще), ваш дочерний процесс будет уничтожен в конце выполнения ls.

Вы можете фактически использовать этот вызов printf для печати некоторых ошибок, например:

 if(pid==0)
    {
        printf("\nI am the child\n");
        execlp("/bin/ls","ls",NULL);
        printf("\nError: Could not execute function %s\n", "/bin/ls");
        _exit(0); //make sure you kill your process, it won't disappear by itself. 
    }
1 голос
/ 27 августа 2013

Причина проста: функции exec () возвращают, только если произошла ошибка.Для того же обратитесь к справочным страницам функций exec ().

Что именно происходит при вызове функций exec ():

execl () не создает новый процесс - он изменяет VADSи связанное содержимое - кроме того, контекст исполнения также изменяется.

  • старый контекст выполнения больше не используется - создается новый контекст выполнения.
    • создается новый, свежий контекст для вновь загруженного приложения, и управление передается планировщику-планировщику, возобновляющему тот же дочерний процесс с вновь доступным контекстом выполнения - с помощью этого выполняется переход к точке входанового приложения в пользовательском пространстве - новое приложение начинает выполняться в том же дочернем процессе.
      • системный стек перезаписывается новым контекстом hw для возобновления main () новой программы в пользовательском пространстве.
    • контекст выполнения и код / ​​data / heap /стек старого приложения в дочернем процессе полностью уничтожен - больше не доступен.
    • только время execve () или execl () вернется к тому же приложению / коду текущего процесса, когда execve () или execl() не может загрузить новое приложение в текущем процессе - это означает, что единственное время, когда execv () / execvl () или семейство вызовов вернутся, - это ошибка при завершении execv () / execl () / семейства вызовов.

Примечание: вы должны проверить возвращаемое значение API системных вызовов семейства exec () для ошибок / кодов ошибок - на основе кодов ошибок / ошибок вы можете завершить текущуюобработать или выполнить какое-либо другое действие.

0 голосов
/ 22 августа 2013
  1. Вы принимаете идентификатор процесса как int тип, но на самом деле, чтобы сохранить идентификатор процесса, вы должны использовать pid_t
  2. Когда вы используете функцию семейства exec, все адресное пространство вызываемого процесса заменяет вызывающий процесс. Итак, теперь последний оператор printf отсутствует в новом процессе, фактически даже идентификатор процесса процесса также не изменился
0 голосов
/ 10 января 2013

после того, как функция execlp () не будет выполнена согласно документации execlp следовательно, ваше выражение printf () "Я все еще ребенок" не выполняется ... !!

...