2013-12-22 3 views
2

멀티 스레드 서버에서 신호 처리 문제가 발생했습니다. 연결 당 하나의 스레드를 생성하지만 SIGINT로 서버를 종료하는 옵션이 필요합니다. 그러나 스레드 중 하나가 신호를 잡을 때 상황이 불쾌 해집니다. 스레드가 주 스레드를 제외하고 신호를받지 못하도록 차단할 수있는 방법이 있습니까?다중 스레드 서버, 신호 처리. POSIX

+0

에 http : // 유래 .com/a/18314115/412080 –

답변

5

스레드는 신호 마스크를 생성하는 스레드로부터 신호 마스크를 상속받습니다.

작성중인 스레드가 "기본"스레드라고 가정하면 스레드를 작성하기 전에 문제의 모든 신호를 차단하고 코드 작성이 완료된 후 작성중인 스레드의 신호를 차단 해제 할 수 있습니다.

스레드의 신호 마스크를 수정하려면 POSIX는 pthread_sigmask()을 정의합니다.


업데이트 : 신호 처리는 다중 스레드 환경에서 일정한 기초에 수행해야

은 흥미로운 접근 방식은 다른 아무것도하지 않고 있지만, 신호를 기다리고 별도의 스레드로 모든 신호를 위임하는 것입니다 sigwait()을 사용하여 도착하십시오.

그렇게하려면

  1. 설정은 이전의 다른 어떤에 "주"스레드에서 pthread_sigmask()를 사용하여 처리하는 신호에 따라 신호 마스크입니다.
  2. 그런 다음 신호를 처리 할 스레드를 만듭니다.
  3. 그런 다음 pthread_sigmask()을 다시 사용하여 "main"스레드의 1.에서 모든 신호를 차단하십시오.
  4. 마지막으로 다른 모든 스레드를 만듭니다.

결과는 1에 지정된 모든 신호는 2에서 만든 스레드에 갈 것이라고 .. 다른 모든 스레드가 1에 지정된 신호 중 하나를 수신하지 않을 것 ..

+0

여기서 문제는 내가 새 스레드를 만들 때마다 연결을 얻을 수 있다는 것입니다. 따라서 스레드를 _all_ 생성 한 후에 신호를 차단할 수는 없습니다. – darenn

+0

@ 업데이트 됨 : 업데이트 된 답변을 참조하십시오. – alk

+0

또 다른 문제는 .. (실행 중) {msgrcv() ...} 동안 내 서버가 루프에서 작동하고 있습니다. 내가 신호를 잡았을 때 나는 거짓으로 실행을 설정했지만 주 스레드는 여전히 msgrcv에 붙어 있습니다. 거기에 어떤 식 으로든 내가 ip를 대기열을 파괴하고 EIDRM 오류를 확인 제외하고 처리 할 수 ​​있습니까? – darenn

0

pthread_sigmask()가 필요한 것입니다. 이 신호를 잡을 것으로 예상되는 스레드에서만 SIGINT 처리를 허용하십시오.

+0

이 접근법은 쓰레드가 생성 될 때부터 쓰레드가'pthread_sigmask()'를 호출 할 때까지 시간을두고 경합을 일으킨다. – alk

+0

@alk yep 그러나 이것은 실제 문제가 아니며 쉽게 여러 가지 방법으로 해결할 수 있습니다. – Netch