É seguro enviar SIGUSR1 para um programa e por quê? [fechadas]

0

Quando você envia SIGUSR1 sinal (digamos que o manipulador de sinal foi definido antecipadamente) para um programa enquanto está executando sleep(100) , o sinal é capturado corretamente, mas sleep(100) é finalizado logo após a captura. Isso pode significar que o envio de um sinal pode forçar a finalização forçada da função interna.

Por exemplo, em um programa de cálculo científico, gostaria de pegar SIGUSR1 e imprimir o progresso. Mas e se eu enviar o sinal enquanto declarações como has_error_occured = true ou should_break_this_roop = true estiverem em execução? Eu acho que isso pode causar um comportamento inesperado.

Como posso usar SIGUSR1 (e SIGUSR2 ) com segurança? Sabe-se que o comando shell dd imprime o progresso quando captura SIGUSR1 . Por que isso é seguro?

Programa de amostra (executei 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();

}
    
por ynn 12.11.2018 / 15:31

1 resposta

5

Você deve definir seu manipulador de sinal usando sigaction (2) em vez de signal (2) , e defina SA_RESTART em sa_flags se você não quiser para interromper uma chamada de sistema de bloqueio.

struct sigaction sa;
sa.sa_handler = your_handler;
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, 0);

Ou, melhor ainda, apenas manipule a interrupção você mesmo.

Se nanosleep (), etc. retornou -1, verifique se errno == EINTR , imprima o progresso e refaça a chamada (sleep () é apenas um invólucro para nanosleep () no linux). Você terá que fazer isso de qualquer maneira se o seu programa crescer para algo mais complexo - não há muito o que fazer com segurança de um manipulador de sinais - veja a página do manual signal-safety (7) no Linux.

    
por 12.11.2018 / 15:59

Tags