현재 개발중인 Linux 배포판에 대해 시스템에서 중요한 프로그램을 작성 중입니다. 충돌을 피하려고 특정 신호를 받으면 스스로 다시 시작해야합니다. 문제는 다시 시작한 후에 해당 신호를 다시 활성화 할 수 없다는 것입니다. 즉, 신호를 두 번 수신 할 수 없습니다. execv() 자체가 실행 된 후 새로운 프로세스가 signal()을 호출하여 신호를 설정하면 SIG_DFL이 반환됩니다. 매번 제가 두 번 연속해서 그것을 부르더라도, 그것은 처음부터 결코 설정되지 않았 음을 나타냅니다. 일부 이상한 깃발이 원래의 과정에서 옮겨 졌습니까?신호가 execv()에서 올바르게 다시 활성화되지 않음
답변
당신은 본질적으로 신호를 재귀 적으로 처리하려고한다는 사실에 파묻혀 있습니다.
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). 수동 sighandler
에 execl
를 호출하기 전에 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);
신호 처리기는 전체 주소 공간을 덮어 exec
exec
때문에 걸쳐 상속되지 않으며, 초기화되지 않은 시그널 핸들러는 잘못된 장소를 가리키는 것입니다. 재설정되지 않는 유일한 시간은 SIG_IGN
(예 : exec
프로세스의 주소 공간에 종속되지 않음)으로 설정된 경우입니다.
- 1. SharePoint 기능이 기본적으로 활성화되지 않음
- 2. 캐슬 윈저 과도 라이프 스타일이 활성화되지 않음
- 3. QWebKit link 클릭 신호가 발생하지 않음
- 4. 웹 응용 프로그램 기능이 기본적으로 활성화되지 않음
- 5. ActiveX 컨트롤을로드했지만 올바르게 활성화되지 않음 (Reg Free COM에서 사용하는 경우에만 해당)
- 6. 스레드가 올바르게 동작하지 않음
- 7. ImageGD가 올바르게 채워지지 않음
- 8. ComboBox가 올바르게 채워지지 않음
- 9. 왜 페이지 번호가 목록보기 및 데이터 페이지에서 올바르게 활성화되지 않은가
- 10. Android DatagramSocket이 올바르게 작동하지 않음
- 11. distinct select가 올바르게 작동하지 않음
- 12. QWidget이 일관되게 업데이트/다시 그려지지 않음
- 13. Perl : 차단 신호가 지연되지 않음 -> 테스트 코드 제공
- 14. Business Objects 버전 3 대체 행/열 색상이 활성화되지 않음
- 15. DataView가 TIMESTAMP에서 올바르게 필터링되지 않음
- 16. AddHandler/RemoveHandler가 올바르게 처리되지 않음
- 17. 양식이 올바르게 리디렉션되지 않음 Wicket
- 18. 테이블 셀이 올바르게 스패닝되지 않음
- 19. 텍스트 상자가 올바르게 표시되지 않음
- 20. PHP 세션이 올바르게 전달되지 않음
- 21. 배경 작업자가 올바르게 작동하지 않음
- 22. Python이 Vim에서 활성화되지 않았습니다
- 23. Capistrano가 다시 시작되지 않음
- 24. JLabel이 다시 칠하지 않음
- 25. C# (다시, 다시?) 변수가 저장되지 않음
- 26. QProcess의 readyReadStandardOutput 신호가 없음
- 27. 잡으려고 권장 신호가 있습니까?
- 28. 은 glib 신호가 비동기입니까?
- 29. UNIX 신호가 손실 됨
- 30. iPhone - UIView 애니메이션이 올바르게 루핑되지 않음
나는 그것을 차단 해제해야한다는 것을 알았습니다. 나는 그것이 바보가 아니었다는 것을 바보로 가정했습니다. 어쨌든, NODEFER를 시도했는데 작동하지 않았지만 exec 호출이 작동하기 전에 핸들러에서이를 차단 해제했습니다. 고맙습니다. – c4757p