2011-11-29 5 views
1

을 사용하여 약간의 프로그램을 작성하여 pipe을 사용하여 통신하는 새 프로세스를 작성했습니다. 방어 프로그래밍을 적용하여 모든 반환 값을 확인합니다. 반환 값이 잘못되었다고 나타내면 모든 리소스를 해제하고 모든 파이프와 부모 프로세스를 닫아서 자식 프로세스가 종료 될 때까지 기다려야합니다. 이제 오류가 발생하면 구제 방법은 무엇입니까? 순간 파이프를 다룰 때 돌발을위한 전략

, 나는 이런 식으로 일을 해요 :

/* initialize pipes */ 
if(pipe(p1fd) == -1) { 
    (void) printError("Could not init pipe 1"); 
    exit(EXIT_FAILURE); 
} 
if(pipe(p2fd) == -1) { 
    (void) printError("Could not init pipe 2"); 
    (void) close(p1fd[0]); 
    (void) close(p1fd[1]); 
    exit(EXIT_FAILURE); 
} 

switch (pid = fork()) { 
    case -1: 
     (void) printError("Could not fork"); 
     (void) close(p1fd[0]); 
     (void) close(p1fd[1]); 
     (void) close(p2fd[0]); 
     (void) close(p2fd[1]); 
     exit(EXIT_FAILURE); 
     break; 
    case 0: /* child process */ 
     break; 
    default: /* parent process */  
     break; 
} 

하나가 더 많은 자원을 필요로하는 경우 이것은 매우 성가신 가져옵니다. 내가 생각한 또 다른 방법은 파이프가 실제로 열렸 으면 돌보지 않고 모든 파이프를 닫는 구제 기능을 제공하는 것입니다 (메모리를 확보하고 하위 프로세스에 wait을 호출하는 것과 동일). 그러나 파이프의 일부가 다른 하위 프로세스/기능으로 전달되므로 이러한 보석금 상환 기능에 필요한 모든 변수가 전역 적이어야합니다.

+2

'goto'이 당신의 친구입니다. –

+0

@mort :'close()'시스템 호출의 리턴 값을 체크하지 않습니다. exit()가 종료되지 않을 것을 기대하지 마라 .-) –

+0

@Vlad : 음,'exit()'에는 반환 값이 없다. – mort

답변

4

당신은 실패 각 분기에 동일한 코드를 반복하지 않도록하기 위해 goto을 사용할 수 goto 일부 사람들이 눈살을 찌푸리게한다

if (pipe(p1fd) == -1) { 
    printError("Could not init pipe 1"); 
    goto pipe1_fail; 
} 

if (pipe(p2fd) == -1) { 
    printError("Could not init pipe 2"); 
    goto pipe2_fail; 
} 

switch (pid = fork()) { 
    case -1: 
     printError("Could not fork"); 
     goto fork_fail; 

    case 0: /* child process */ 
     ... 
     exit(...); 

    default: /* parent process */  
     ... 
     exit(...); 
} 

fork_fail: 
close(p2fd[0]); 
close(p2fd[1]); 

pipe2_fail: 
close(p1fd[0]); 
close(p1fd[1]); 

pipe1_fail: 
exit(EXIT_FAILURE); 
2

있지만, 그것은 종종 used for error handling, 전자입니다. 지. in the Linux kernel. 그러나 코드를 잘 구조화 된 상태로 유지하고이를 사용하는 데 과장하지 마십시오. 여기

예 :

/* initialize pipes */ 
if(pipe(p1fd) == -1) { 
    (void) printError("Could not init pipe 1"); 
    goto error; 
} 

if(pipe(p2fd) == -1) { 
    (void) printError("Could not init pipe 2"); 
    goto closep1fd; 
} 

switch (pid = fork()) { 
    case -1: 
     (void) printError("Could not fork"); 
     goto closep2p1fd; 
    case 0: /* child process */ 
     break; 
    default: /* parent process */  
     break; 
} 

closep2p1fd: 
    close(p2fd[0]); 
    close(p2fd[1]); 
closep1fd: 
    close(p1fd[0]); 
    close(p1fd[1]); 
error: 
    exit(EXIT_FAILURE); 
    return -1; // maybe better if it is a deeply nested function 
관련 문제