Потерянные сигналы от ребенка к родителю - PullRequest
4 голосов
/ 10 апреля 2019

Я создаю несколько дочерних процессов, которые посылают сигнал родительскому процессу и умирают. Я просто считаю их. Но я никогда не получаю правильный счет. Некоторые сигналы никогда не улавливаются обработчиком.

Как мне это написать?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <sys/wait.h>

int ended = 0;

void handler(int sig){
    ended++;
}

int main(int argc, char **argv){
    int i;
    pid_t pid, ppid;

    if (signal(SIGUSR1, handler) < 0) {
        fprintf(stderr, "signal failed.\n");
        exit (-1);
    }

    ppid = getpid();

    for (i = 0; i < 50; i++){
        if ((pid = fork()) < 0){
            fprintf(stderr, "fork failed.\n");
            exit(-1);
        }
        if (pid == 0){  
            kill(ppid, SIGUSR1);
            exit(0);
        }       
    }

    while (wait(NULL) > 0);

    printf("ended = %d\n", ended);

    return 0;
} 

Выходные данные для этой программы иногда 47, другие 39 ... но никогда 50

Ответы [ 3 ]

3 голосов
/ 10 апреля 2019

Проблема здесь в том, что сигнал действует как аппаратное прерывание, где вашей функцией-обработчиком будет ISR (процедура обработки прерывания).Затем, если несколько сигналов одного и того же значения происходят «одновременно», ядро ​​Linux рассматривает их как только один сигнал.Сигнал не предназначен для использования таким образом.Сигнал должен использоваться, чтобы сообщить о состоянии процесса другому.Для достижения связи между процессами вы должны использовать механизмы IPC (InterProcess Communications), такие как очередь, сокеты или каналы.

1 голос
/ 12 апреля 2019

Спасибо

Я обнаружил, что проблему можно решить с помощью сигналов реального времени. Просто меняю SIGUSR1 с помощью SIGRTMIN. Сигналы в реальном времени ставятся в очередь (http://man7.org/linux/man-pages/man7/signal.7.html).

Есть ли какие-либо негативные побочные эффекты в этом решении?

0 голосов
/ 10 апреля 2019

это работало ..

#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int ended = 0;

void handler(int sig)
{
    ended++;
}

    int main(int argc, char **argv)
    {
        int i;
        pid_t pid, ppid;

        if (signal(SIGUSR1, handler) < 0)
        {
            fprintf(stderr, "signal failed.\n");
            exit (-1);
        }

        ppid = getpid();

        for (i = 0; i < 50; i++)
        {
            if ((pid = fork()) < 0)
            {
                fprintf(stderr, "fork failed.\n");
                exit(-1);
            }
            if (pid == 0)
            {
                kill(ppid, SIGUSR1);
                exit(0);
            }
        }

        while (wait(NULL) > 0);

        printf("ended = %d\n", ended);

        return 0;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...