POSIX 스레드 및 신호
POSIX 스레드와 POSIX 신호가 어떻게 상호작용하는지 이해하기 위해 노력해왔습니다.특히 다음 사항에 관심이 있습니다.
- 신호가 전달되는 스레드를 제어하는 가장 좋은 방법은 무엇입니까(애초에 치명적이지 않은 것으로 가정).
- 신호가 도착했음을 다른 스레드(실제로 비지 상태일 수 있음)에 알리는 가장 좋은 방법은 무엇입니까?(신호 핸들러에서 pthread 조건 변수를 사용하는 것은 좋지 않다는 것은 이미 알고 있습니다).
- 신호가 발생했다는 정보를 다른 스레드에 안전하게 전달하려면 어떻게 해야 합니까?이것이 신호 핸들러에서 발생할 필요가 있습니까?(일반적으로 다른 스레드를 종료하고 싶지 않습니다.더 미묘한 접근법이 필요합니다).
TclX 패키지를 스레드 지원으로 변환하거나 분할하여 유용한 부품 지원 스레드를 만드는 방법을 알아보고 있습니다.신호는 특히 관심 있는 부분 중 하나입니다.
- 신호가 전달되는 스레드를 제어하는 가장 좋은 방법은 무엇입니까?
@zoli2k에서 알 수 있듯이 처리할 모든 신호(또는 각각 특정 신호 책임이 있는 스레드 세트)를 처리하기 위해 단일 스레드를 명시적으로 지정하는 것은 좋은 기술입니다.
- 신호가 도착했음을 다른 스레드(실제로 사용 중일 수 있음)에 알리는 가장 좋은 방법은 무엇입니까?[...]
- 신호가 발생했다는 정보를 다른 스레드에 안전하게 전달하려면 어떻게 해야 합니까?이것이 신호 핸들러에서 발생할 필요가 있습니까?
'최고'라고는 말하지 않겠습니다만, 제 추천은 다음과 같습니다.
에서 필요한 모든 신호 차단main
모든 스레드가 신호 마스크를 상속하도록 합니다.그런 다음 특수 신호 수신 스레드를 신호 구동 이벤트 루프로 만들고, 새로 도착한 신호를 다른 스레드 내 통신으로 디스패치합니다.
가장 간단한 방법은 또는 를 사용하여 스레드가 루프 내의 신호를 받아들이도록 하는 것입니다.스레드는 신호를 어떻게든 변환합니다.아마도 브로드캐스트 할 수 있습니다.pthread_cond_t
더 많은 I/O로 다른 스레드를 웨이크업하고 애플리케이션 고유의 스레드 세이프 큐에 명령을 큐잉합니다.
또는 특수 스레드를 사용하여 신호를 신호 핸들러에 전달할 수 있으며, 신호를 처리할 준비가 되었을 때만 전달을 위해 마스크 해제됩니다(핸들러를 통한 신호 전달은, 를 통한 신호 수신보다 에러가 발생하기 쉬운 경향이 있습니다).sigwait
단, 가족).이 경우 수신기의 신호 핸들러는 간단한 비동기 신호 세이프 액션을 수행합니다.sig_atomic_t
플래그, 호출sigaddset(&signals_i_have_seen_recently, latest_sig)
,write
() 비파형 셀프파이프 등에 대한 바이트그런 다음 마스킹된 메인 루프에서 스레드는 위와 같이 신호 수신을 다른 스레드로 전달합니다.
(업데이트된 @caf는 올바르게 다음과 같이 지적합니다.sigwait
접근법이 우수합니다.)
POSIX 표준에 따라 모든 스레드는 시스템에 동일한 PID로 표시되어야 하며,pthread_sigmask()
모든 스레드에 대해 신호 차단 마스크를 정의할 수 있습니다.
PID당 하나의 신호 핸들러만 정의할 수 있기 때문에, 저는 하나의 스레드로 모든 신호를 처리하여pthread_cancel()
실행 중인 스레드를 취소해야 하는 경우그것은 에 대항하는 바람직한 방법이다.pthread_kill()
스레드에 대한 정리 함수를 정의할 수 있기 때문입니다.
일부 오래된 시스템에서는 적절한 커널 지원이 없기 때문에 실행 중인 스레드의 PID가 부모 스레드의 PID와 다를 수 있습니다.Linux 2.4에서 Linux Threads를 사용한 신호 처리는 FAQ를 참조하십시오.
현재 상황:
- 신호는 다양한 메이저클래스로 분류됩니다.일반적으로 그 중 일부는 프로세스를 종료하고(SIGILL), 그 중 일부는 아무것도 실행할 필요가 없습니다(SIGIO, 어쨌든 비동기 IO를 올바르게 실행하는 것이 용이합니다).이 두 가지 클래스는 액션이 필요하지 않습니다.
- SIGWINCH 등의 신호는 즉시 처리할 필요가 없습니다(X11로부터의 이벤트와 마찬가지로 편리할 때까지 큐잉할 수 있습니다).
- 까다로운 것은 당신이 하는 일을 방해함으로써 그들에게 대응하고 싶지만, 실타래를 닦아내는 수준까지는 가지 않는 것입니다.특히 인터랙티브모드의 SIGINT는 응답성을 유지할 필요가 있습니다.
난 아직 정리해야 해signal
대sigaction
,pselect
,sigwait
,sigaltstack
POSIX(및 비 POSIX) API의 기타 모든 비트와 조각이 포함되어 있습니다.
IMHO, Unix V 신호 및 Posix 스레드가 잘 혼합되지 않습니다.Unix V는 1970년입니다.POSIX는 1980;)
취소 포인트가 있으며, 1개의 애플리케이션에서 신호와 pthread를 허용하면 결국 각 콜에 루프가 기록되고 EINTR이 예기치 않게 반환될 수 있습니다.
그래서 Linux 또는 QNX에서 멀티스레드를 프로그래밍해야 하는 경우는 1개를 제외한 모든 스레드의 모든 신호를 마스킹했습니다.
Unix V 신호가 도착하면 프로세스는 스택을 전환합니다(이것은 Unix V에서 프로세스 내에서 얻을 수 있는 최대 동시성).
다른 투고에서도 알 수 있듯이 스택스위칭의 대상이 되는 Posix 스레드를 시스템에 통지할 수 있습니다.
신호 핸들러 스레드가 작동하게 되면 신호 정보를 다른 스레드에서 사용할 수 있는 문명화된 것으로 변환하는 방법에 대한 의문이 남습니다.스레드 간 통신을 위한 인프라가 필요합니다.한 가지 패턴은 각 스레드가 진행 중인 메시징 메커니즘의 대상이 되는 행위자 패턴입니다.
따라서 다른 스레드를 취소하거나 삭제(또는 기타 이상한 것)하는 대신 신호 컨텍스트에서 신호 핸들러 스레드로 신호를 마샬링한 다음 액터 패턴 통신 메커니즘을 사용하여 신호 관련 정보를 필요로 하는 액터에게 의미론적으로 유용한 메시지를 보내야 합니다.
언급URL : https://stackoverflow.com/questions/2575106/posix-threads-and-signals
'programing' 카테고리의 다른 글
vue.js에서 스타일을 계산하거나 사용하는 방법 (0) | 2022.07.08 |
---|---|
파이 차트가 완전히 렌더링되지 않음 (0) | 2022.07.08 |
C에서 "함수에 대한 충돌 유형"을 얻을 수 있습니다. 이유는 무엇입니까? (0) | 2022.07.08 |
ThreadLocal 변수를 언제 어떻게 사용해야 합니까? (0) | 2022.07.08 |
링크 리스트에서 루프를 검출하려면 어떻게 해야 합니다. (0) | 2022.07.08 |