2014-01-14 3 views
1

У меня есть следующий фрагмент кода:Зачем активировать обработчик сигнала asio немедленно?

#include <signal.h> 
#include <boost/asio.hpp> 
#include <iostream> 

void startAsyncWaitForSignal(boost::asio::io_service& ioService) 
{ 
    boost::asio::signal_set signals{ioService}; 
    signals.add(SIGTERM); 
    signals.async_wait(
     [&ioService](boost::system::error_code errorCode, int signalNumber) 
     { 
      std::cerr << errorCode.message() << std::endl; 
      if (!errorCode) { 
       std::cerr << "received signal " << signalNumber << std::endl; 
       startAsyncWaitForSignal(ioService); 
      } 
     } 
    ); 
} 

int main() { 
    boost::asio::io_service ioService; 
    startAsyncWaitForSignal(ioService); 
    ioService.run(); 
} 

Я бы ожидать, что эта программа ждать, пока первый SIGTERM не прибыл, а затем ждать до следующего, а затем снова на следующий ...

Однако программа немедленно завершается следующий вывод:

Operation canceled 

Что является причиной этой немедленной операции отменить? Я попытался создать объект io_service :: work, но это только изменило тот факт, что ioService.run() не был закончен, но signal_set все равно был отменен немедленно.

Я использую boost 1.54. Существует bug fix related to asio/signals in 1.55, но это похоже на другую проблему.

+3

При выходе 'startAsyncWaitForSignal()' 'локальная переменная signal_set' разрушается и' async_wait' вызов будет отменен. 'Signal_set' должен жить немного дольше ... –

+0

Если вы сделаете это как ответ, я соглашусь с этим. Большое спасибо! –

ответ

4

При удалении startAsyncWaitForSignal() изменяется местная signal_set, а вызов async_wait() отменяется. signal_set должен жить немного дольше. Переместить его из startAsyncWaitForSignal() и передать его в качестве параметра, например:

#include <signal.h> 
#include <boost/asio.hpp> 
#include <iostream> 

void startAsyncWaitForSignal(boost::asio::io_service& ioService, boost::asio::signal_set& signals) 
{ 
    signals.async_wait(
     [&ioService, &signals](boost::system::error_code errorCode, int signalNumber) 
     { 
      std::cerr << errorCode.message() << std::endl; 
      if (!errorCode) { 
       std::cerr << "received signal " << signalNumber << std::endl; 
       startAsyncWaitForSignal(ioService, signals); 
      } 
     } 
    ); 
} 

int main() { 
    boost::asio::io_service ioService; 
    boost::asio::signal_set signals{ioService}; 
    signals.add(SIGTERM); 
    startAsyncWaitForSignal(ioService, signals); 
    ioService.run(); 
} 
+1

nice A, но «немного дольше» - это ребенок бессмысленного измерения? – NoSenseEtAl

+0

'signal_set' должен оставаться в пределах всей продолжительности вызова' async_wait'. –

+0

@SamMiller Я думаю, что это не на 100% правильно выражено (я знаю, что вы знаете, что вы имеете в виду!). В исходном образце кода область действия 'signal_set' такова: целая продолжительность' async_wait'. Но масштаб должен быть еще шире: пока обработчик ожидания не был вызван. –

Смежные вопросы