我在linux上使用 gcc4.7 c ++和 boost 。
我有一个使用boost :: signals2的EventDispatcher类,如下所示。 onUpdate()
可由多个线程调用
class EventDispather
{
public:
void subscribe(Listener l)
{
_signal.connect(l)
}
void onUpdate(Data data)
{
_signal(data);
}
private:
boost::signals2::signal<void (Data)> _signal;
};
现在我想在类中再添加一个信号来处理一些低优先级的侦听器。当onUpdate()执行时,它首先通知高优先级侦听器。然后应该在低优先级线程中调用低优先级并立即返回。新代码如下:
class EventDispather
{
public:
void subscribe(Listener l, Priority priority=high)
{
if(priority == high)
{
_signal.connect(l);
}
else
{
_signalLowPriority.connect(l);
}
}
void onUpdate(Data data)
{
_signal(data);
//how to trigger _signalLowPriority in a low priority thread?
}
private:
boost::signals2::signal<void (Data)> _signal;
boost::signals2::signal<void (Data)> _signalLowPriority;
};
问题:
_signalLowPriority()
而不等待?onUpdate()
使用时创建一个新线程,但重用一个线程..怎么做?如果我的目标可以在使用标准库和/或boost时完成,那将是很棒的,但如果真的有帮助,我可以使用任何其他库。
答案 0 :(得分:2)
获得所需内容的最简单方法是将_signalLowPriority
调用发布到boost::asio::io_service
,该调用在一个单独的线程中运行。这是一些(未经测试的)代码:
class EventDispather : enable_shared_from_this<EventDispather> // simplifies lifespan management, wrt async. slot invocations
{
EventDispather() : work_(new io_service::work(io_)) // prevent io_serivce::run() from exiting when running out of work
{
auto self = shared_from_this();
// capturing "self" (even without using it) ensures that this instance will outlive the async. "queue" that uses `io_` and `_signalLowPriority` members
thread th([self, this]() { io_.run(); });
set_priory_with_some_native_api(thread.native_handle());
th.detach();
}
void stop()
{
// after work_ is reset, io_service::run() will process the pending functors and then exit; thus, the above lambda will get destroyed - along with its captured "self" shared_ptr
work_.reset();
}
void onUpdate(Data data)
{
_signal(data);
// if io_ is running in 1 thread, all _signalLowPriority invocations will be serialized
io_.post([data, this]() { _signalLowPriority(data); });
}
private:
io_service io_;
shared_ptr<io_serive::work> work_;
// add here all your signals etc...
};
注意:虽然_signalLowPriority
是线程安全的,但它的插槽必须准备好在一个单独的线程中调用!
当然,您可以thread
或enable_shared_from_this
使用shared_ptr
,std
,boost
。