Как лучше всего определить, когда дочерний процесс завершился с использованием сигналов - PullRequest
0 голосов
/ 04 июня 2018

У меня есть дочерний процесс (созданный с помощью fork), я хочу узнать у родителя, где он умирает, и что-то там делать.В функции handle я хочу использовать функцию класса-члена, поэтому мне нужно передать указатель на «this».

Я думал о двух направлениях:

Option1:

использовать sigaction;

static RpcCmd* rpcCmdPtr = nullptr;// global pointer to save class  

в основном:

  rpcCmdPtr  = this;  
  struct sigaction act;  
  memset(&act, 0, sizeof(act));  
  act.sa_handler = **sigchldHdl**;  
  sigaction(SIGCHLD, &act, 0)  

/* SIGCHLD handler. */  
void **sigchldHdl**(int sig)  
{  
  if(rpcCmdPtr != nullptr)  
  {  
    rpcCmdPtr->sigHandler(sig);  
  }  
}

void RpcCmd::sigHandler(int sig)  
{ // here are some code...}

Вариант 2:

использовать другой поток, передать указатель на"this" в качестве аргумента и используйте там signalfd;

    static void * sigThread(void * arg)  
    {  
    rpcCmd* rpcCmdPtr = static_cast<rpcCmd*>(arg)  
    sigprocmask(SIG_BLOCK, &mask, NULL)  

    /* Create a file descriptor from which we will read the signals. */  
    sfd = signalfd (-1, &mask, 0);  

    while (1) {  
        struct signalfd_siginfo si;  
        res = read (sfd, &si, sizeof(si));  
        if (si.ssi_signo == SIGCHLD)  
            // more code ...  
    } 

Я хочу знать ЧТО - лучший способ, а ПОЧЕМУ ?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Внимательно прочитайте Сигнал (7) и Сигнал-безопасность (7) (и помните, что большинство стандартных библиотек C ++, включая new, контейнеры , etc ...- основан на не асинхронно-безопасных функциях, таких как malloc, поэтому вы обычно не можете вызывать эти функции C ++ из обработчика сигнала)

Вы забыли большеПереносная опция 3:

  • при инициализации процесса, создать трубу (7) (для «самостоятельного» процесса)

  • перед входом в цикл обработки событий установите обработчик чтения для этого канала (он прочитает (2) байт из него)

  • install (используя sigaction (2) ) обработчик сигнала для вашего сигнала, который просто записывает (2) один или несколько байтов в канал.Обратите внимание, что write является безопасным для асинхронного сигнала.

Этот подход предложен Qt, смотрите его Вызов функций Qt из UnixОбработчики сигналов page.

Кстати, многие библиотеки циклов обработки событий (часто выше poll (2) ...) уже обрабатывают SIGCHLD

0 голосов
/ 04 июня 2018

option 1 это зло.

  1. только async-signal-safe Функция может быть вызвана внутри обработчика сигнала.И многие функции не могут быть вызваны внутри обработчика сигнала, например, malloc free и printf

  2. обработчик сигнала должен быть реентерабельным, ваш RpcCmd::sigHandler, вероятно, нереентрант

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