2011-08-23 1 views
6

부모 주소 공간이 "ls"명령으로 바뀌는 forkl 및 execlp 프로그램을 시도했습니다. 내가 프로그램을 아이Fork and Execlp

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

의 마지막 줄을 실행하면

#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(); 
    } 
} 

는 인쇄되지 않습니다. 왜?

답변

16

exec 성공적인 경우 가족 기능이 반환되지 않습니다.

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

exec 함수 계열은 새로운 프로세스 이미지로 현재 프로세스 이미지를 대체한다. 새 이미지는 새 프로세스 이미지 파일이라는 일반 실행 파일로 구성됩니다. 호출 한 프로세스 이미지가 새 프로세스 이미지로 덮어 쓰기되기 때문에 성공적인 임원이 반환하지 않아야합니다.

exec 함수 중 하나가 호출 프로세스 이미지로 돌아 오면 오류가 발생했습니다. 리턴 값은 -1이되어야하고, errno는 에러를 나타내도록 설정되어야한다.

4

exec 함수는 단순히 명령을 실행하지 않습니다. 그들은 실제로 선택한 실행 파일 (귀하의 경우 /bin/ls)에 의해 프로세스의 실행 컨텍스트를 대체합니다.

즉, ls 함수는 프로세스를 종료하거나 (끝내거나 주 함수를 반환하는 등) 종료하기 때문에 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. 
    } 
0

을 함수 때 execlp 후() 때 execlp 따라서 귀하의 printf() 문의 문서에 따라 실행되지 않습니다 " 아직도 나는 아이이다. "처형 당하지 않는다 ... !!

-3
  1. 당신은 int 유형으로 프로세스 ID를 복용하고 있지만 간부 가족 함수가 호출 프로세스의 전체 주소 공간이 호출 프로세스를 대체 사용하는 경우 실제로 저장 프로세스 ID에 당신은 pid_t
  2. 를 사용해야합니다. 그래서, 마지막 printf 문은 새로운 프로세스에 존재하지 않습니다. 사실 프로세스의 프로세스 id도 변경되지 않습니다.
+0

몇 가지 좋은 점이 있지만 새로운 프로세스에서는 pid가 확실히 다릅니다. 또한 exec는 프로세스가 성공할 경우에만 대체하고, 그렇지 않으면 exec 호출을 계속 수행합니다. – techdude

1

이유는 간단합니다 : exec() 함수는 오류가있는 경우에만 리턴합니다 발생했습니다. exec() 함수의 같은 참조 맨 페이지. 간부() 함수가 호출 될 때 정확히 무슨 일이 일어나고 무엇

:

execl 함수() 새로운 프로세스를 생성하지 않습니다 - 그것은 VADS과 관련된 내용을 수정 -뿐만 아니라, 실행 컨텍스트 도 수정됩니다.

  • 이전 실행 컨텍스트가 더 이상 사용되지 않습니다. 새 실행 컨텍스트가 만들어집니다.
    • 새로운, 신선한 컨텍스트가 새로로드 된 응용 프로그램에 생성되고 컨트롤이 scheduler- 스케줄러에 전달되는 새로 가능한 실행 컨텍스트와 같은 아이 과정을 다시 시작 -이를 사용, 점프 는 항목에 실행 사용자 공간에서 새 응용 프로그램의 포인트 - 새 응용 프로그램이 동일한 하위 프로세스에서 실행되기 시작합니다.
      • 사용자 공간에서 새 프로그램의 main()을 다시 시작하기위한 새로운 hw 컨텍스트로 시스템 스택을 덮어 씁니다.
    • 실행 컨텍스트와 자식 프로세스에서 이전 응용 프로그램의 코드/데이터/힙/스택은 완전히 파괴되지 않는다 - 더 이상 사용할. 의미 만 -을 execve() 또는 execl 함수()는 에게 현재 프로세스의 새로운 애플리케이션을로드하는 데 실패 할 때
    • 만 시간을 execve() 또는 execl 함수()는 동일한 애플리케이션에 반환은/현재 프로세스의 코드 은 시간 execv()/execl()/family 패밀리를 완료하는 데 오류가있는 경우 execv()/execvl() 또는 통화 그룹이 반환됩니다.

참고 :이 오류/에러 코드 임원() 가족 시스템 호출하는 API의 반환 값의 유효성을 검사해야합니다 - 오류/오류 코드를 기반으로, 당신은 현재의 프로세스를 종료 또는 일부를 취할 수있다 기타 조치.