2012-08-11 26 views
1

정보를 처리하는 무한 루프가있는 서버에서 C로 작성한 프로그램이 있습니다. 각 루프를 완료하는 데 약 5 분이 걸립니다. 나는 쉘 스크립트에서 다음과 같은 기능을 가지고 싶다 :
정상적으로 C 응용 프로그램 종료

  • C 프로그램을 종료
  • 만들기 소스
  • 프로그램 실행
문제가

, 난 몰라 ctrl + c와 같은 일을하지 않고 종료하도록 내 C 프로그램에 알려주는 방법을 알고 있습니다. 종료하기 전에 현재 처리중인 정보를 처리하는 것이 좋습니다.

Ctrl 키 + C를 같은

답변

4

프로세스를 종료하고 정상적으로 종료하도록 지시하는 POSIX 표준 방법은 SIGTERM 신호를 보냅니다. 응용 프로그램에 따라 SIGINT에서 종료하는 것이 적절할 수도 있고 그렇지 않을 수도 있습니다. 이는 프로세스를 중단하고 종료하지 않기위한 것입니다. (Control-c는 SIGINT을 전송합니다.)

좁은 루프에 플래그를 넣으십시오. 종료하기 쉽지만 즉시 종료 할 수있을 때 플래그를 확인하십시오. 귀하의 경우 SIGTERM을 수령하면 즉시 시스템 로그에 메시지가 표시 될 수 있으며 다음 5 분 이내에 종료하겠다고 약속 할 수 있습니다.

귀하의 신호 핸들러는 다음과 같이 표시됩니다

static int signalled; // if nonzero, what signal have we been sent? 

static void SignalHandler(int signum) { 
    signalled = signum; 
} 

나는 초당 몇 번을 의미 모든 I/O 작업, 후 글로벌 static 변수 signalled를 확인합니다.

static __sighandler_t sh, si, st; 

static void catch_signals(void) { 
    if ((sh = signal(SIGHUP, SignalHandler)) == SIG_IGN) signal(SIGHUP, SIG_IGN); 
    if ((si = signal(SIGINT, SignalHandler)) == SIG_IGN) signal(SIGINT, SIG_IGN); 
    if ((st = signal(SIGTERM, SignalHandler)) == SIG_IGN) signal(SIGTERM, SIG_IGN); 
    signalled = 0; 
} 

static void restore_signals(void) { 
    signal(SIGHUP, sh); 
    signal(SIGINT, si); 
    signal(SIGTERM, st); 
} 

(.이 코드는 라이브러리에서, 그래서 나는 것들을 내가 그들을 발견하는 방법을두고 추가 조심 해요)

보너스 :

여기 신호를 잡아 복원 내 코드입니다 트릭 : 시간이 만료되면 (이것은 TV 녹화 라이브러리 임), 타이머는 단지 signalled = SIGTERM으로 설정하고, 동일한 로직을 사용하여 레코더를 정상적으로 종료합니다.여기

+0

@dear downvoter 이것은 좋은 대답입니다. 팝 오버 텍스트 "이 답변은 유용하지 않습니다"를 정당화하기 위해 의견을 제공 할 수 있습니까? – cnicutar

3

, 나는 오히려 SIGINT에 대한 신호 처리기를 설정 또는 무엇이든 당신이 원하는 당신 후 정리를 할 수는 현재 itsel에게

를 종료하기 전에 작업중인 정보 처리를 완료 할 그것을 받으십시오. 그러나 처리기 자체에서 정리를 수행하면 안됩니다..

volatile sig_atomic_t do_cleanup = 0; 
void handler(int sig) 
{ 
    do_cleanup = 1; 
} 

는 그런 다음 메인 루프에서 당신은 때 do_cleanup하고 종료하십시오 테스트해야합니다. EINTR 오류를 제대로 처리하지 않았다면 올바르게 처리해야합니다.

+1

. 변수는 휘발성이어야합니다. –

+0

@ JohannesSchaub-litb 맞습니다. 나는 엉성했습니다. – cnicutar