Неоднозначное поведение системного вызова kill в C - PullRequest
0 голосов
/ 14 февраля 2019

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

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

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

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

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

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

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

0 голосов
/ 14 февраля 2019

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

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

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

...