2012-09-10 3 views
1

, 내가 배운 그 재진입이 신호 처리기 내부에 피해야 할 실패,하지만 난 뭔가를 한 경우 기능 :전역 변수를 사용하지만 exit를 사용하는 함수는 여전히 신호 처리기에서 피해야합니다. 나는 C와 유닉스 프로그래밍에 대해 뭔가를 공부로

int main(int argc, char** argv){ 
    ... 
    fileFd=open(...) 
    signal(SIGUSR1, signalHandler) 
    ... 
} 


void signalHandler(int signo){ 
    switch(signo){ 

    case SIGUSR1: 
     myExit(EXIT_FAILURE); 
     break; 

    default: 
     break; 

    } 
} 

이 myExit이

인 경우
void myExit(int ret){ 

    ...DO STUFF... 
    close(fileFd); 
    exit(ret); 

} 

및 fileFd는 전역 변수이며, 내가 제대로 기억한다면 그 myExit 비 재진입의 수 ...하지만 여전히 그것은 출구가 발생할 경우에도 신호 처리기에서 사용하는 문제입니다 프로그램? 바보 같은 질문이라면 어떤 도움을 주시면 감사하겠습니다.

+0

재진입에 관한 것이 아니라 비동기 안전성에 관한 것입니다. 나가는 것이 좋을 것입니다. –

+0

논리적으로 그렇지 않습니다. 프로그램이 종료되면 종료 후에도 걱정할 필요가 없습니다. * "종료 후"가 없기 때문입니다. * –

답변

3

신호 처리기에서 안전하게 수행 할 수있는 유일한 방법은 휘발성 sig_atomic_t 변수를 설정하는 것입니다. 신호가 수신되었는지 (신호 처리기 외부) 확인하여 프로그램의 메인 루프에서 처리하십시오. 비 휴대용 것들을 시작해야한다면 적어도 _Exit() 또는 _exit()를 사용하는 것이 좋습니다. 특정 C 라이브러리는 특정 기능이 신호 안전성을 보장하지만 이는 분명히 다른 시스템에서 작동하는 것이 보장되지 않습니다.

0

"... 할아버지는 ..."에 따라 문제가 발생할 수 있습니다. 거기에서 수행 된 작업이 동일한 포인터를 해제하는 것과 같이 두 번 수행되지 않을 경우 충돌이 발생할 수 있습니다.

close (fileFD)가 전역 상태에 영향을주는 유일한 것이며 파일 액세스 API가 파일의 이중 닫기를 허용하는 경우 특정 상황에서 문제가되지 않을 수도 있습니다.

+0

UNIX'close'는 위험 할 수 있습니다. 안전하게 두 번 호출 할 수 없습니다. 그 동안 fd가 다시 사용되었을 수도 있기 때문에 동일한 fd를 사용할 수 있습니다. – nneonneo

0

비동기 안전하지 않은 기능을 사용하는 경우 여전히 안전하지 않습니다. USR1과 같은 비동기 신호는 일부 라이브러리 코드에서 중요한 섹션 (잠긴 섹션)의 중간을 포함하여 프로그램의 임의의 두 명령어 사이에서 발생할 수 있습니다.

예를 들어 malloc의 중간에서 중단이 발생하면 신호 처리기에서 free (예 : 정리)을 호출하면 교착 상태가됩니다.

+1

그래서 async-signal-safe 함수 만있는 경우 (사실 필자는 쓰기 및 닫기 만 했으므로 async-signal-safe 목록 아래의 man 7 신호에 나열되어 있음) 나는 괜찮습니다. 맞습니까? – cifz