2009-06-21 2 views
3

현재 개발중인 Linux 배포판에 대해 시스템에서 중요한 프로그램을 작성 중입니다. 충돌을 피하려고 특정 신호를 받으면 스스로 다시 시작해야합니다. 문제는 다시 시작한 후에 해당 신호를 다시 활성화 할 수 없다는 것입니다. 즉, 신호를 두 번 수신 할 수 없습니다. execv() 자체가 실행 된 후 새로운 프로세스가 signal()을 호출하여 신호를 설정하면 SIG_DFL이 반환됩니다. 매번 제가 두 번 연속해서 그것을 부르더라도, 그것은 처음부터 결코 설정되지 않았 음을 나타냅니다. 일부 이상한 깃발이 원래의 과정에서 옮겨 졌습니까?신호가 execv()에서 올바르게 다시 활성화되지 않음

답변

8

당신은 본질적으로 신호를 재귀 적으로 처리하려고한다는 사실에 파묻혀 있습니다.

signal()을 사용하여 신호 처리기를 등록하면 해당 신호 번호는 신호 처리기가 반환 될 때까지 차단됩니다. 실제로는 신호 처리기가 호출 될 때 kernel/libc가 해당 신호 번호를 차단하고 신호 처리기가 반환 한 후에는 해당 신호 번호를 차단합니다. 신호 처리기에서 돌아 오지 않는 대신 (execl 새 이진수) SIGUSR1은 차단 된 채로 두 번째로 잡히지 않습니다.

/proc/</pid>/status은 첫 번째로 SIGUSR1을 보내기 전후에 검사하여 볼 수 있습니다.

전에 :

$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)" 
SigBlk: 0000000000000000 
SigCgt: 0000000000000200 

후 : SigCgt 신호 (10)가 등록 나타내는

$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)" 
SigBlk: 0000000000000200 
SigCgt: 0000000000000200 

하는 것으로 (개수가 비트 필드이고, 10 비트가 설정되고, SIGUSR1 총점있는 대한 man signal(7) 참조 숫자들). SIGUSR이 프로세스로 전송되기 전에 SigBlk이 비어 있지만 신호를 보낸 후에 SIGUSR1을 포함합니다.

당신은이 문제를 해결하는 방법은 두 가지가 있습니다

A). 수동 sighandlerexecl를 호출하기 전에 SIGUSR 차단을 해제 :

sigset_t sigs; 
sigprocmask(0, 0, &sigs); 
sigdelset(&sigs, SIGUSR1); 
sigprocmask(SIG_SETMASK, &sigs); 

B). 신호 처리기를 등록하려면 signal 대신 SA_NODEFER 플래그와 함께 sigaction을 사용하십시오. 이렇게하면 이 신호 처리기 내에서 차단되지 않습니다.

struct sigaction act; 
act.sa_handler = signalhandler; 
act.sa_mask = 0; 
act.sa_flags = SA_NODEFER; 
sigaction(SIGUSR1, &act, 0); 
+0

나는 그것을 차단 해제해야한다는 것을 알았습니다. 나는 그것이 바보가 아니었다는 것을 바보로 가정했습니다. 어쨌든, NODEFER를 시도했는데 작동하지 않았지만 exec 호출이 작동하기 전에 핸들러에서이를 차단 해제했습니다. 고맙습니다. – c4757p

1

신호 처리기는 전체 주소 공간을 덮어 execexec 때문에 걸쳐 상속되지 않으며, 초기화되지 않은 시그널 핸들러는 잘못된 장소를 가리키는 것입니다. 재설정되지 않는 유일한 시간은 SIG_IGN (예 : exec 프로세스의 주소 공간에 종속되지 않음)으로 설정된 경우입니다.

+0

이렇게 생각합니다. 내가 말한 것은 execv'ing 후에 새로운 프로세스가 신호를 다시 설정할 수 없다는 것입니다. 내가하는 일과 상관없이, 시그널 핸들러로부터 프로세스를 execv'ing 한 후에, 같은 시그널을 다시 설정할 수는 없다. – c4757p

+0

테스트 할 수있는 코드가 있습니까? 나는 지금 이것에 대해 정말로 궁금해. –

+0

예. 그것을 '죽여라'는 시도를해라. 한번만 할 수 있습니다 - 모든 후속 시도를 무시합니다. http://www.box.net/shared/tgfaef5l8i – c4757p

관련 문제