Родитель не получит сигнал при вызове sigqueue - C - PullRequest
0 голосов
/ 18 апреля 2020

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

void handler(int signumber,siginfo_t* info,void* nonused)
{
    printf("Signal with number %i has arrived\n",signumber);
    switch (info->si_code){
        case SI_USER: printf("Process (PID number %i) sent the signal (calling kill)\n",info->si_pid); break;
        case SI_TIMER: printf("It was sent by a timer\n");
            printf("Additional data: %i\n",info->si_value.sival_int);
            //  timer_delete(t_id); //stops timer
            break;
        case SI_QUEUE: printf("It was sent by a sigqueue, sending process (PID %i)\n",info->si_pid);
            printf("Additional value: %i\n",info->si_value.sival_int);
            //  struct student* d=(struct student*)info->si_value.sival_ptr;
            //  printf("Additional value: %s, %i\n",d->name,d->year);
            break;
        default: printf("It was sent by something else \n");
    }
}

И попытка отправить сигнал с дополнительные данные с использованием sigqueue:

struct sigaction action;

action.sa_sigaction = handler;
sigemptyset(&action.sa_mask);
action.sa_flags=SA_SIGINFO;
if (sigaction(SIGTERM, &action, NULL) < 0) 
{
    perror("Sigaction failed");
    exit(1);
}
pid = fork();
if (pid == -1) 
{
    perror("Forking error");
    exit(EXIT_FAILURE);
}
if (pid == 0) //child process
{
            printf("Child process (PID %i), will send a SIGTERM to parent %i\n",getpid(),getppid());
//            sleep(1);
//            kill(getppid(),SIGTERM); //this works

            //sending an integer as an additional data
            sleep(1);
            union sigval s_value_int={5};
            sigqueue(getppid(),SIGTERM,s_value_int);
            printf("Child process ended\n");
}
else
{
            printf("Parent (PID %i) waits for a signal from child (PID %i) \n",getpid(),pid);
            pause();
            wait(NULL);
            printf("Parent process ended\n");
}

Проблема в том, что я не получаю никакой информации (от обработчика), а родительский процесс останавливается навсегда (в ожидании сигнала от дочернего элемента из-за pause() вызов), поэтому я подозреваю, что сигнал никогда не приходит. «Дочерний процесс завершен» выводится на консоль.

Интересно, что если я посылаю сигнал через kill(), родитель получает его очень хорошо, и обработчик также выводит дополнительную информацию. К сожалению, мне нужна альтернатива sigqueue, потому что я должен отправить дополнительное целое число в качестве данных родителю. Я читал о возможных потерях сигналов из-за того, что поступает слишком много сигналов, и они встают в очередь. Может ли это быть проблемой и в моем случае? Если так, что можно сделать, чтобы это исправить? Большое спасибо

...