SIGUSR1을 프로그램에 보내는 것이 안전합니까? 왜? [폐쇄]

SIGUSR1을 프로그램에 보내는 것이 안전합니까? 왜? [폐쇄]

프로그램이 실행되는 동안 프로그램에 신호를 보내면 SIGUSR1(신호 처리기가 미리 설정되어 있다고 가정) sleep(100)신호는 올바르게 포착되지만 sleep(100)포착된 후 즉시 종료됩니다. 이는 신호를 보내면 일부 내부 기능이 강제로 종료될 수 있음을 의미할 수 있습니다.

예를 들어, 과학 컴퓨팅 프로그램에서 진행 상황을 캡처하고 인쇄하고 싶습니다 SIGUSR1. 하지만 has_error_occured = trueor 같은 명령문이 실행되는 should_break_this_roop = true동안 신호를 보내면 어떻게 될까요 ? 이로 인해 예기치 않은 동작이 발생할 수 있다고 생각합니다.

SIGUSR1(및 )을 안전하게 사용하는 방법은 무엇입니까 SIGUSR2? 우리 모두 알고 있듯이 쉘 명령 ddSIGUSR1. 왜 그렇게 안전합니까?


샘플 프로그램(내가 실행한 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) 매뉴얼 페이지리눅스에서.

관련 정보