2015-02-05 3 views
0

내 프로세스 호출 할당의 구성 요소 중 하나가 무한 루프를 실행하는 것으로 보이며 그 이유를 알 수 없습니다. 여기 문제 영역 인 것 같다.프로그램의 무한 루프

D=fork(); 
if (D==0)execv("/home/8/myfiles/DD.c",arg); 


while(temp != 4){    //return value of D is 4 
A = wait(&temp);} 
exit(1); 

코드의 목표는 D가 종료 될 때까지 대기하는 것이다. 주석과 마찬가지로 D는 "exit (4);"로 끝납니다. 그래서 내가 아는 한, 그것이 temp를 할 때 4가 할당된다는 것을 의미합니까? 아니면 여기서 뭔가 잘못하고있는 것입니다.

답변

0

tempwait()으로 반환 된 값은 종료 된 응용 프로그램의 종료 상태를 반환하지 않습니다. 해당하는 경우 종료 코드가 포함 된 압축 된 값을 반환합니다.

WIFEXITED()WEXITSTATUS()과 같은 the manual page for wait()에 정의 된 매크로를 사용하여 상태 코드의 의미를 결정하십시오. 하위 프로세스가 비정상적으로 종료되는 경우 (예 : 충돌) wait()은 원하는 것 이외의 값을 반환 할 수 있습니다. 에 관계없이

if (D==0)execv("/home/8/myfiles/DD",arg); 

, 자식 프로세스를 기다리는 처리의보다 강력한 방법은 다음과 같습니다 : 그것이 있어야처럼

0

선은

if (D==0)execv("/home/8/myfiles/DD.c",arg); 

보인다

A = wait(&temp); 
if(temp != 4) 
{ 
    // Print a message or do whatever makes sense 
    // to deal with the unexpected value. 
} 

exit(1); 
0

귀하 코드는 다소 불투명하게 작성됩니다. 실패 할 수있는 시스템 호출 (또는 execv()의 경우 간단히 반환 된 후 종료한다고보고 함)의 반환 값을 테스트해야합니다. 루프 코드는 SIGCHLD 신호가 무시 될 경우 wait()에서 유효한 상태를 얻을 수 없다는 것을 고려해야합니다. 그리고 그의 answerduskwuff이 지적한대로 적절한 매크로를 사용하여 종료 상태를 테스트해야합니다. 현재 테스트는 경험적으로, 신호 4 (Mac OS X에서 SIGILL)를 수신했기 때문에 자식이 종료되었는지 테스트합니다.

난 당신이 더 같은 코드를 사용해야한다고 생각 :

int pid; 
if ((pid = fork()) < 0) 
{ 
    fprintf(stderr, "fork failed\n"); 
    exit(1); 
} 
if (pid == 0) 
{ 
    const char *cmd = "/home/8/myfiles/DD.c"; 
    execv(cmd, arg); 
    fprintf(stderr, "failed to execute %s\n", cmd); 
    exit(1); 
} 

int corpse; 
int status; 
while ((corpse = wait(&status)) > 0) 
{ 
    if (WIFEXITED(status) && WEXITSTATUS(status) == 4) 
     break; 
    printf("PID %d exited with status 0x%.4X\n", corpse, status); 
} 
exit(0); 

당신은 시체가 PID와 동일한 지 확인할 수 있습니다 - 그건 그냥 종료 상태를 확인보다 더 신뢰할 수있다. 대기 루프에서 인쇄를 원하지 않는다고 결정할 수도 있습니다. 그건 합법적 인 일이지만, 디버깅 목적으로 유지할 수도 있습니다. 루프를 시작하기 전에 하위의 PID를 인쇄 할 수도 있습니다. 프로그램이 시작된 유일한 프로세스가 fork()의 프로세스라는 것을 알고 있더라도 반복해야한다는 것에 유의하십시오. 프로세스가 다른 프로세스를 임 시한 경우 첫 번째 프로세스에 하위 프로세스가있는 경우 실행 된 프로세스는 하위 프로세스로 남아 있으며 분기 된 프로세스와 실행 된 프로세스 전에 종료 될 수 있습니다.

DD.c이라는 실행 파일 (프로그램 또는 스크립트)을 갖는 것은 드문 경우입니다. 이름이 .c 인 파일은 일반적으로 C 소스 파일입니다. 일반적으로 다음을 사용하는 것이 가장 좋습니다.

execv(args[0], args); 

실행 파일의 이름은 명령의 이름입니다. 그것은 의무적 인 것은 아니지만. 일반적으로 명령 실행이 실패 할 경우 실행할 수없는 명령의 이름을보고하는 것이 좋습니다.