Почему SIGINT перестает спать больше одного раза? - PullRequest
1 голос
/ 08 мая 2019

Я не понимаю, почему после первого выполнения функции kill функция сна не приостанавливает родительский процесс.После доставки SIGINT генерируется много процессов.Кроме того, кажется, что генерируется переменное количество процессов.Требуется ли обработчик для SIGINT для очистки первого SIGINT от ожидающих сигналов?

void handler(int s) {
    int status;
    wait(&status);
    printf("\n in the handler");
    if (WIFSIGNALED(status)) {
        int sig=WTERMSIG(status);
        printf("\n child stopped by signal %d\n",sig);
    }
    if (WIFEXITED(status)) {
        int ex=WEXITSTATUS(status);
        printf("\n child stopped with exist status %d\n",ex);
    }
}

int main() {
    int pid,len, count, ret;
    char s[1024];
    signal(SIGCHLD,handler);
    while(1) {
        pid=fork();
        if (pid==0) {
            printf("\n Write something ");
            scanf("%s",s);
            len=strlen(s);
            printf("\n Characters: %d",len);
            return 1;
        }
        else {
            sleep(20);
            kill(pid,SIGINT);
        }
    }
}

1 Ответ

2 голосов
/ 08 мая 2019

SIGCHLD из предыдущего, вызывающего смерть ребенка kill поступает как раз в то время, когда вы находитесь в следующем sleep.

Сон - это прерываемая функция.Если обработчик сигнала работает, когда ваш поток находится в нем, sleep будет прерван.Итак, вы переходите к следующему kill, которое косвенным образом вызовет еще один SIGCHLD, который, скорее всего, произойдет, когда ваша следующая итерация перейдет в спящий режим, что приведет к нескольким пропущенным снам.

Если вы вставите sleep(1)до fork(), он должен (практически) сдвигать время точно так, чтобы следующий sleep(20); не прерывался.

(Я отношусь к этому как к быстрому и грязному эксперименту.хорошая идея полагаться на «корректировки», подобные этой, в производственном коде (или использовать printf в обработчиках сигналов в этом отношении).

...