Boost.Asio没有为已添加到boost::asio::signal_set
然后通过signal_set::remove()
,signal_set::clear()
或销毁signal_set
删除的信号指定结果处理程序状态。特别是,Signal Set Service requirements中的任何关联操作都没有指定后置条件。
快速一目了然的signal_set_service::add()
implementation:
::sigaction(signal_number, &sa, 0)
和signal_set_service::clear()
implementation:
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
::sigaction(reg->signal_number_, &sa, 0)
表明,要sigaction()
呼叫没有处理以前安装的处理程序和结果的默认处理程序当通过signal_set_service
删除信号时,操作被注册。 Boost.Asio的设置信号动作为默认设置后
随着信号可以传递,但是应用程序代码之前一直能够分配自己的处理程序,可以考虑使用pthread_sigmask()
挡住io_service
内的所有信号。一旦信号从signal_set
中删除,通过sigaction()
分配所需的处理程序,然后解除信号的阻塞。
下面是一个完整的例子证明这种方法:
#include <iostream>
#include <boost/asio.hpp>
void signal_handler(int signal_number)
{
std::cout << "signal_handler(): " << signal_number << std::endl;
}
int main()
{
// Force scope to control io_service lifetime.
{
boost::asio::io_service io_service;
// Boost.Asio will register an internal handler for SIGQUIT.
boost::asio::signal_set signal_set(io_service, SIGQUIT);
signal_set.async_wait(
[](const boost::system::error_code& error,
int signal_number)
{
std::cout << "siganl_set.async_wait handler: "
<< signal_number << std::endl;
// Block SIGQUIT.
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGQUIT);
assert(pthread_sigmask(SIG_BLOCK, &signal_mask, NULL) == 0);
});
// Send SIGQUIT to this process.
raise(SIGQUIT);
// By the time raise() returns, Boost.Asio has handled SIGQUIT with its
// own internal handler, queuing it internally. At this point, Boost.Asio
// is ready to dispatch this notification to a user signal handler
// (i.e. those provided to signal_set.async_wait()) within the
// io_service event loop.
// Prior to calling the io_service, SIGQUIT is not blocked.
io_service.run();
// The user provided handler was invoked and has blocked SIGQUIT.
}
// Send SIGQUIT to this process.
raise(SIGQUIT);
// Even though Boost.Asio has set the default handler for SIGQUIT, the
// signal is blocked, so the signal has been placed into a pending state.
// Register a custom handler for SIGQUIT.
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_handler = &signal_handler;
assert(sigaction(SIGQUIT, &sa, 0) == 0);
// Unblock SIGQUIT.
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGQUIT);
assert(pthread_sigmask(SIG_UNBLOCK, &signal_mask, NULL) == 0);
// Upon unblocking, the pending SIGQUIT signal is delivered and handled
// by the handler registered via sigaction.
std::cout << "Fin" << std::endl;
}
,其输出:
$ ./a.out
siganl_set.async_wait handler: 3
signal_handler(): 3
Fin
我认为这是一个奇怪的行为不恢复旧的sigaction对象。非常非常奇怪。谢谢你的帮助!带信号阻塞可能是唯一可靠的解决方法。 – GreenScape 2014-09-01 06:38:55