2012-09-13 2 views
0

우선, 저는 C에서 새로운 것입니다. 저는 레거시 C 코드를 상속 받았습니다. 이 응용 프로그램에서 시간 초과가 올바르게 작동하지 않습니다. 신호와 알람을 사용하여 타임 아웃을 만듭니다. 나는 두 가지 모두에 대해 읽었으며 여전히 문제가 있습니다.C에서 타임 아웃으로 신호 및 알람 사용

signal(SIGALRM, timeouthandler); 
alarm(3); 
...(connection to a server that may hang)... 

alarm(0); 

timeouthandler(){ 
...(connection to a server that may hang)... 
} 

이제 코드의 다른 섹션에 시간을 추가해야만 정상적으로 작동합니다.

signal(SIGALRM, timeouthandler2); 
alarm(3); 
...(log the time out)... 

alarm(0); 

timeouthandler2(){ 
...(log the time out)... 
} 

왜 두 번째 시간 초과가 작동하지 않습니까? 신호와 알람 사이의 연결은 무엇입니까? 이 작업을 수행하는 데있어 클리너 (복잡하지 않아야 함) 방식이 있습니다. 또한이 두 시간 제한을 모두 포함하는 다른 시간 초과 처리기가 필요할 것입니다. 감사!!

EDIT : 좋아요, 그래서 나는 한 번에 두 가지 타임 아웃을 할 수없는 것처럼 보입니다. 제가하려고하는 것을 설명해 드리겠습니다. 연결할 서버 목록이 있습니다. 나는 각 연결에 3 초 동안 연결하고 시간 초과하지 않기를 원한다. 그런 다음 서버 목록에 대해 global 시간 초과를 설정하여 모든 연결 시간의 총 시간이 12 초를 초과하면 시간 초과되어 계속 이동하도록합니다. 내가 할 수있는 또 다른 방법이 있니?

답변

0

신호와 알람 간의 관계는 알람이 보류중인 신호라는 것입니다. 그 알람 신호 (SIGALRM)는 앞으로 제공 될 것입니다. man alarm 그러나 요약은 alarm(5);이 SIGALRM을 5 초 내에 보내고 alarm(0);이 (아직 전달되지 않은) 경보를 취소한다는 것을 요약합니다. 신호 처리 함수 (signal() 호출의 두 번째 매개 변수)는 신호가 전송 될 때 호출됩니다 (신호 처리기가 반환 할 때까지 프로그램의 주 실행을 일시 중단합니다).

왜 작동하지 않는지 ... 무슨 일이 일어나지 않았습니까? 세부 정보를 입력하지 않았습니다.

일을하는 더 깨끗한 방법은 ... 정확히 무엇을하려고하는지 명확하지 않으므로 대답 할 수 없습니다. ...code...이 3 초 이상 걸리는 이유는 무엇입니까? 그것이 이해된다면 당신의 질문에 답을 줄 수있을 것입니다.

+0

좋아요, 그래서 나는 한 번에 두 가지 타임 아웃을 할 수없는 것처럼 보입니다. 제가하려고하는 것을 설명해 드리겠습니다.연결할 서버 목록이 있습니다. 나는 각 연결에 3 초 동안 연결하고 시간 초과하지 않기를 원한다. 그런 다음 모든 연결 시간의 총 시간이 12 초를 초과하면 시간 초과되어 계속 이동하도록 서버 목록에 대해 "글로벌"시간 초과를 원합니다. 내가 할 수있는 또 다른 방법이 있니? – Bill

+0

다른 방법은 사용중인 OS에 따라 다릅니다. OS가 posix 세마포어를 제대로 지원한다면, 그 작업을 두 번째 쓰레드로 나눌 수 있습니다. 주 스레드는 두 번째 스레드를 시작한 다음 해당 스레드의 세마포를 기다리고 작업이 완료되었음을 나타냅니다. 이 semaphore wait는'sem_timedwait()'로 끝나기 때문에 타임 아웃 할 수있다. 작업자 스레드는 단일 서버에 연결을 시도하고 성공할 경우 플래그를 설정하여 주 스레드가 상태를 알고 있으므로 세마포를 게시합니다 (주 스레드를 즉시 깨우기 위해). 12 초의 글로벌 타임 아웃은 알람으로 수행 될 수 있습니다. – mah

0

초 수가 0이면 새 알람을 예약하지 않습니다. alarm manual page :

초가 0이면 새 알람()이 예약되지 않습니다.

뿐만 아니라 : 어떤 경우

이전에 설정된 알람()이 취소됩니다.

따라서 alarm 번을 호출하면 이전에 설정 한 알람을 취소 할 수 있습니다.

0

alarm(2) 일정 초 단위로 SIGALRM 신호가 전달되고 은 이전 요청을 취소합니다. 이전 요청을 취소합니다. 이렇게 여러 개의 제한 시간을 설정할 수는 없습니다. 그것은 하나 또는 둘 다입니다.

Linux를 사용하는 경우 오염 가능성이있는 timerfd 기능을 탐색 할 수 있습니다.