Почему я не могу поймать у ребенка сигнал, который посылает родитель? - PullRequest
0 голосов
/ 19 января 2019

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

Мой код:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

void handler(int signumber){
  printf("Signal with number %i has arrived\n",signumber);
}

int main(){

  sigset_t sigset;
  sigemptyset(&sigset); //empty signal set
  sigaddset(&sigset,SIGTERM); //SIGTERM is in set
  //sigfillset(&sigset); //each signal is in the set
  sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blockedhere

  signal(SIGTERM,handler); //signal and handler is connetcted

  pid_t child=fork();
  if (child>0)
  {
    printf("I'm parrent\n");
    printf("Waits 2 seconds, then send a SIGTERM %i signal (it is blocked)\n",SIGTERM);
    sleep(2);
    kill(getppid(),SIGTERM); 
    printf("I sent it.\n");   
  }
  else
  {
    wait(NULL);
    sleep(2);
    printf("I'm the child wainting for signal.\n");

    sigprocmask(SIG_UNBLOCK,&sigset,NULL); 


    int status;
    wait(&status);
    printf("Child process ended\n");
  }
  return 0;
}

И вот результат:

I'm parrent
Waits 2 seconds, then send a SIGTERM 15 signal (it is blocked)
I'm the child wainting for signal.
Child process ended
I sent it.

И еще одна вещь, я знаю, я должен использовать sigsuspend(sigset); вместо обработчика, потому что printf небезопасен в обработчике , но как я могу использовать его в этом случае?

1 Ответ

0 голосов
/ 26 января 2019

Ожидание в основном для получения детских статусов (обычно для наблюдения за изменениями статуса ребенка). Использование этого в ребенке не имеет большого смысла. Да, вы можете использовать sigsuspend для ожидания сигнала. Это может выглядеть так:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>


#define WRITE(Str) (void)write(1,Str,strlen(Str))
void handler(int signumber)
{
    WRITE("Signal arrived\n");
}

int main(){

  sigset_t sigset;
  sigemptyset(&sigset); //empty signal set
  sigaddset(&sigset,SIGTERM); //SIGTERM is in set
  sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blockedhere

  signal(SIGTERM,handler); //signal and handler is connetcted

  pid_t child=fork();
  if(0>child) return EXIT_FAILURE;
  if (child>0) {
    int status;
    printf("I'm the parent\n");
    printf("Waits 2 seconds, then send a SIGTERM %i signal (it is blocked)\n",SIGTERM);
    sleep(2);
    kill(child,SIGTERM);
    printf("I sent it.\n");
  }
  else
  {
    sigemptyset(&sigset); //the child has a different addr-space
                          //so this won't affect the parent
    printf("I'm the child waiting for signal.\n");
    sigsuspend(&sigset);
    printf("Child process ended\n");

  }
  return 0;
}

Для получения дополнительной информации см. Справочные страницы по отдельным системным функциям. Вам также следует проверять коды возврата, даже если большинство этих конкретных функций обычно не работают, если вы не вызываете их неправильно (хотя некоторые делают, например, fork () может вполне реально работать, если у вас недостаточно памяти).

...