2011-11-01 2 views
0

단일 스레드 C 응용 프로그램에 정의 된 종료 후크 처리기가 있습니다.CRITICAL 섹션을 완료하기 위해 C 응용 프로그램을 종료하는 올바른 방법?

int main(int argc, char * argv[]){ 
    //Shutdown hook for CTRL-C 
    (void) signal(SIGINT, shutdownHook); 
    ... 
    ... 
} 

사용자가 종료 훅이 시작됩니다 CTRL-C 안타 그래서 ...

void shutdownHook(int sig){ 
    rc = wmq_sender_stop(errorStr); 
    if (rc != 0){ 
     printf("\n%s\n", errorStr); 
    } 
    while(transactionRunning == TRUE){ 
     sleep(1); 
     printf("Transaction still running\n"); 
    } 
    .... 
    .... 
} 

당신은 내가 (공유 lib에)는 "wmq_sender_stop"루틴을 호출 그 위에 볼 수 있습니다 본질적으로 변수를 FALSE로 설정하여 해당 공유 라이브러리의 루프를 종료합니다.

변수 "running"은 (아마도) 공유 라이브러리에서 실행되는 메인 루프를 멈출 것입니다.

while(running == TRUE){ 
... 
... 
} 

오전 데 문제는 모두가 100 % 작동하는 내 리눅스 박스에 ...하지만 난 BIG 강력한 서버에 응용 프로그램을 설치할 때 그것은 "wmq_sender_stop"를 호출하고 변수 벌금을 설정하지만 보인다 응용 프로그램이 "while (running == TRUE)"변수를 종료 할 수 있도록 서버에서 너무 빠르게 실행되고 있습니다 ..... 또는 단순히 주 응용 프로그램으로 너무 빨리 돌아가고 "while (transactionRunning == TRUE

:) "루프 그냥 계속 ... 실행

는 본질적으로 BIG 서버에 내가 CRTL-C를 치면 다음 화면에 continuosly 출력 0

아마도 여기에 스레드를 만들고 상호 통신해야하지만 매우 빠른 서버에서도 종료하기 전에 "공유 라이브러리의 루프"를 "중요한 코드/트랜잭션"을 우아하게 허용하는 더 쉬운 방법은 아닙니다. ? 그리고 그것은 왜 내 리눅스 노트북에서 작동합니까?

스레드를 사용해야하는 경우 가장 빠르고 가장 빠른 방법은 무엇입니까? 현재 CALLBACKS ....을 사용하고 있습니다 만, 최고의 IPC가 쓰레드에 대해 무엇인지 모르십니까? 도움을

덕분에, 많은 return를 통해 신호 처리기를 떠나보다 왜 단지 wmq_sender_stop()를 호출하지 린톤

+0

리눅스 박스에서 'transactionRunning'을 FALSE로 설정하는 것은 무엇입니까? 단일 스레드 응용 프로그램 인 경우 변경하는 'sleep/printf'루프가 아닙니다 ... –

+1

일반적으로 신호 처리기 (또는 I/O)에서 장기 실행 작업을 수행하는 것은 좋지 않습니다. 신호 처리기 대신 주 스레드에 "신호"를 보내고 거기에서 모든 작업을 수행하십시오. –

+0

당신이 app이 단일 쓰레드라고 말했기 때문에, 공유 라이브러리는 app 루프와 SIGINT 핸들러에서 기다리는 루프를 종료 할 기회가 없다. interessting 사실은 비록 당신이 그것을해서는 안되지만 리눅스 박스에서 원하는대로 작동하는 것처럼 보입니다. 서버의 동작은 나에게 완벽하게 보인다. – alk

답변

2

running (및 transactionRunning도)이 volatile으로 선언되어 있는지 확인하십시오. 그렇지 않으면 C 컴파일러는 일부 상황에서 값을 캐시 할 수 있습니다. 지금은 volatile을 "이 값은 신호 처리기로 변경 될 수 있습니다"라고 생각하십시오. 이 같은 코드를 조심해야

참고 :

rc = wmq_sender_stop(errorStr); 

당신은 신호 처리기에서, 당신이 함수는 시그널 핸들러에서 호출하는 것이 안전 것을 더 나은 희망을 가지고 그렇게한다면. 대부분의 기능은 그렇지 않습니다. (여러 스레드에서 안전하게 호출 할 수있는 함수도 신호 처리기에서 호출하기에 안전하지 않습니다.)

마지막 문제는 코드가 단일 스레드인데도 신호 처리기에서 반환하지 않으면 어떻게됩니까? 메인 루프가 빠져 나왔어? 신호 처리기는 응용 프로그램의 기존 스레드 중 하나에서 실행됩니다.일반적으로 신호 처리기에서 수행하고자하는 유일한 작업은 volatile으로 표시된 글로벌 변수의 값을 변경 한 다음 반환하는 것입니다.

+0

좋은 지적 : 나는'running'을 휘발성이라고 선언하는 것에 완전히 동의한다. 왜 당신이'wmq_sender_stop'가 시그널 핸들러로부터 호출 될 수 없는지 설명했다면, 나는 당신의 답을 표기했을 것입니다. – alk

+0

@alk :'wmq_sender_stop'에 대해서는 아무 것도 모르니까, 안전하다고 가정 할 이유가 없습니다. 대부분의 함수는 (예를 들어'printf'를 포함해서) 시그널 핸들러로부터 호출하기에 안전하지 않습니다. 사람들에게 upvotes를 보류하고 있다고 말할 필요는 없으며, 단지 설명을 요구할 수 있습니다. –

+0

최악의 경우를 가정하면 가장 안전한 접근 방법입니다. 감사합니다 ... - 투표에 관련없는 쪽지를 사용하십시오. – alk

0

감사. 공유 라이브러리의 루프가 종료되므로 앱이 수행합니다. 그렇습니까?

+0

하지만 시간 문제가 있습니까? Shard 라이브러리의 루프가 종료되기 전에 주 응용 프로그램이 종료되면 어떻게됩니까? –

+0

@Lynton Grice 왜 메인 앱 엔드가 종료되어야합니까? – alk

관련 문제