如何在 Boost.Asio 中完成工作项时调用函数
How to call a function when a work item is finished in Boost.Asio?
我想实现一个命令队列,它与线程池同时处理传入的命令(因此当所有线程都在工作时,队列会暂时增长)。我想在命令工作者启动和完成时向调用方发布回调。我的实现基于 Asio 网站上的此示例。
有没有办法连接到这些事件并以某种方式发出信号?我想避免命令函子知道回调(因为显然我可以在命令函子中调用回调)。
要说明的伪代码(为简洁起见,省略了初始化和错误处理):
class CommandQueue
{
public:
void handle_command(CmdId id, int param)
{
io_service.post(boost::bind(&(dispatch_map[id]), param));
// PSEUDOCODE:
// when one of the worker threads start with this item, I want to call
callback_site.cmd_started(id, param);
// when the command functor returns and the thread finished
callback_site.cmd_finished(id, param);
}
private:
boost::asio::io_service io_service;
asio::io_service::work work;
std::map<CmdId, CommandHandler> dispatch_map; // CommandHandler is a functor taking an int parameter
CallbackSite callback_site;
};
有没有办法在不让命令函子依赖于回调站点的情况下做到这一点?
我最初的反应是,std::future
s是你想要的,因为 boost-asio 现在甚至已经内置了对它们的支持。但是,您将其标记为c ++ 03,因此您将不得不使用boost::future。
基本上,您将 boost::p romise 传递给要传递给asio
的任务,但事先调用它get_future
并存储与promise
共享状态的future
值。任务完成后,您可以调用promise::set_value
。在另一个线程中,您可以通过调用future::is_ready
(非阻塞)或future::wait
(阻塞)来检查是否发生这种情况,然后在调用相应的回调函数之前从中检索值。
例如,值集可以是示例中的CmdId
,用于确定要调用的回调。
因此,
您想要的是构建当其中一个run()
命令开始处理命令,然后在返回时执行某些操作时发生的情况。
就个人而言,我通过包装函数调用来做到这一点:
class CommandQueue
{
public:
void handle_command(CmdId id, int param)
{
io_service.post(boost::bind(&CommandQueue::DispatchCommand, this,id,param));
}
private:
boost::asio::io_service io_service;
asio::io_service::work work;
std::map<CmdId, CommandHandler> dispatch_map; // CommandHandler is a functor taking an int parameter
CallbackSite callback_site;
void DispatchCommand(CmdId id, int param)
{
// when one of the worker threads start with this item, I want to call
callback_site.cmd_started(id, param);
dispatch_map[id](param);
// when the command functor returns and the thread finished
callback_site.cmd_finished(id, param);
}
};
这也是我想处理调度命令中的异常时使用的模式。您还可以发布不同的事件,而不是以内联方式运行它们。
相关文章:
- 即使没有调用这个递归函数,它是如何工作的?
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 推理类型如何工作"auto"和按引用调用?
- 以下代码如何工作以每次为唯一调用堆栈唯一实例化模板函数?
- 递归函数调用在后台工作
- std::async 如何工作:为什么它会调用这么多次复制/移动?
- QLibrary 函数在第一次调用时工作缓慢
- 工作线程一直在等待,condition_variable甚至调用了notify_all
- 虚拟基类在内部如何工作?编译器如何解析对基方法的调用?
- 在新作用域中使用unique_lock是否等效于在使用共享资源的工作结束时解锁调用
- 从Excel VBA调用C++DLL只能从Visual Studio中的调试实例工作
- 异步操作的 Asio 处理程序在其同步对应项正常工作时不会调用
- 如何使功能"run"工作。程序在调用运行时退出
- 当在函数调用中递增值时,程序正常工作,但是如果我们在单独的行中增加值而不是呼叫函数,则会出现错误.为什么
- 在线程中调用线程会给我带来错误,如果我只调用该函数,则可以正常工作
- boost::asio 使用 post() 时没有调用处理程序,当直接调用函数时有效(io_context有工作)
- 为什么用未申报的变量工作调用函子
- 引用调用在 c++ 中如何工作?
- winsock连接调用崩溃如果多个线程运行,则在一个线程中正常工作
- C Google Mock -Expect_Call() - 期望在不直接调用时无法正常工作