프로그램이 실행되는 동안 프로그램에 신호를 보내면 SIGUSR1
(신호 처리기가 미리 설정되어 있다고 가정) sleep(100)
신호는 올바르게 포착되지만 sleep(100)
포착된 후 즉시 종료됩니다. 이는 신호를 보내면 일부 내부 기능이 강제로 종료될 수 있음을 의미할 수 있습니다.
예를 들어, 과학 컴퓨팅 프로그램에서 진행 상황을 캡처하고 인쇄하고 싶습니다 SIGUSR1
. 하지만 has_error_occured = true
or 같은 명령문이 실행되는 should_break_this_roop = true
동안 신호를 보내면 어떻게 될까요 ? 이로 인해 예기치 않은 동작이 발생할 수 있다고 생각합니다.
SIGUSR1
(및 )을 안전하게 사용하는 방법은 무엇입니까 SIGUSR2
? 우리 모두 알고 있듯이 쉘 명령 dd
은 SIGUSR1
. 왜 그렇게 안전합니까?
샘플 프로그램(내가 실행한 kill -SIGUSR1 xxxxx
):
#include <iostream>
#include <csignal>
#include <unistd.h>
void my_handler(int signal) {
; //some instructions
}
void just_sleep() {
std::cout << "sleep() starts.\n";
sleep(100); //not wait for 100s if a signal caught
std::cout << "sleep() ends.\n"; //executed even if a signal caught
}
int main() {
signal(SIGUSR1, my_handler);
just_sleep();
}
답변1
다음을 사용하여 신호 처리기를 설정해야 합니다.신호 동작(2)바꾸다신호(2), 차단 시스템 호출을 중단하지 않으려면 설정하십시오 SA_RESTART
.sa_flags
struct sigaction sa;
sa.sa_handler = your_handler;
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, 0);
또는 더 나은 방법은 방해를 직접 처리하는 것입니다.
nanosleep() 등이 -1을 반환하는지 확인하고 errno == EINTR
진행 상황을 인쇄한 다음 호출을 다시 실행하세요(sleep()은 Linux에서 nanosleep()의 래퍼일 뿐입니다). 프로그램이 더 복잡해지면 어쨌든 이 작업을 수행해야 합니다. 신호 처리기를 통해 안전하게 수행할 수 있는 작업은 많지 않습니다.signal-safety(7) 매뉴얼 페이지리눅스에서.