Неоднозначное поведение системного вызова kill в C

Я сделал эту программу, и вывод пока не имеет особого смысла для меня. Может кто-нибудь объяснить, что происходит?

void handler1a(int x){
    printf("A\n");
}

int main(){
    signal(SIGUSR1, handler1a);
    int p = fork();
    if(p==0)
    {
        sleep(5);
        printf("L \n");
    }
    else
    {
        kill(0,SIGUSR1);
        kill(0,SIGUSR1);
        kill(0,SIGUSR1);
        //kill(0,SIGUSR1);
        wait(NULL);
    }
}

С 3 сигналами убийства мой выход - 5А и 1л. С 2 сигналами уничтожения выход - 4A и 1L. С 4 сигналами убивания, выход - 6А и 1л. Кажется, что до 2 сигналов уничтожения, и родительский, и дочерний процессы используют мой пользовательский обработчик, но каким-то образом один из них не использует обработчик или не получает сигнал уничтожения после получения сигнала, который он уже дважды (это объясняет, почему только один A печатается, когда я добавляю еще один системный вызов kill после 2 системных вызовов kill).

2 ответа

Сигналы не поставлены в очередь. Таким образом, если вы отправляете один и тот же сигнал процессу несколько раз, он может обрабатываться любое количество раз от 1 до количества отправлений сигнала.

Или, другими словами, для каждой комбинации процесса и сигнала сигнал может находиться в сигнальном состоянии. Если вы отправляете сигнал процессу, когда этот процесс уже находится в сигнальном состоянии для этого сигнала, ничего не происходит.

Процесс не может иметь двух ожидающих сигналов SIGUSR1. Либо SIGUSR1 ожидает, либо нет.

Вот kill вызывается родительским процессом P с 0 в качестве значения pid, которое означает, что все процессы в его группе (самP, а также дочерний элемент C) получат сигнал, и для его обработки будет использован тот же пользовательский обработчик сигнала.

Если вы отправляете в процесс C несколько сигналов одного типа (SIGUSR1 здесь), они не будут поставлены в очередь, потому что этот сигнал будет заблокирован, пока не будет обработан первый полученный, и они будут отброшены.

Только когда обработчик сигнала для C возвращается, C готов снова обработать сигнал. Это объясняет, почему в выводе из вызова C обработчика меньше "A".

Вы можете увидеть, какой процесс вызвал обработчик, добавив printf("A %d\n", getpid()) внутри обработчика.

Другие вопросы по тегам