C++ 如何在Boost.Asio中完成工作项时调用函数?

C++ 如何在Boost.Asio中完成工作项时调用函数?,c++,boost,boost-asio,c++03,C++,Boost,Boost Asio,C++03,我想实现一个命令队列,它与线程池同时处理传入的命令(因此,当所有线程都在工作时,队列会临时增长)。我想在命令工作程序启动和完成时向调用方发出回调。我的实现是基于Asio网站的 有没有办法与这些事件挂钩并以某种方式发出信号?我希望避免命令函子知道回调(因为显然我可以在命令函子内部调用回调) 用于说明的伪代码(为简洁起见,省略了初始化和错误处理): class命令队列 { 公众: void handle_命令(CmdId,int param) { io_service.post(boost::bin

我想实现一个命令队列,它与线程池同时处理传入的命令(因此,当所有线程都在工作时,队列会临时增长)。我想在命令工作程序启动和完成时向调用方发出回调。我的实现是基于Asio网站的

有没有办法与这些事件挂钩并以某种方式发出信号?我希望避免命令函子知道回调(因为显然我可以在命令函子内部调用回调)

用于说明的伪代码(为简洁起见,省略了初始化和错误处理):

class命令队列
{
公众:
void handle_命令(CmdId,int param)
{
io_service.post(boost::bind(&(dispatch_map[id]),param));
//伪代码:
//当一个工作线程以该项开始时,我想调用
回调_site.cmd_已启动(id,param);
//当命令函子返回且线程完成时
回调_site.cmd_已完成(id,param);
}
私人:
boost::asio::io_服务io_服务;
asio::io_服务::工作;
std::map dispatch_map;//CommandHandler是接受int参数的函子
CallbackSite callback\u站点;
};

有没有一种方法可以做到这一点,而不让命令函子依赖于CallbackSite?

我最初的回答是,如果现在已经有了,s就是您想要的。然而,你已经标记了它,因此你将不得不将就

基本上,您将a传递给要传递到
asio
的任务,但事先调用
get\u future
,并存储
future
值,该值与
promise
共享状态。任务完成后,您可以调用
promise::set_value
。在另一个线程中,您可以通过调用
future::is_ready
(非阻塞)或
future::wait
(阻塞)来检查是否发生了这种情况,然后在调用相应的回调函数之前从中检索值


e、 g.在您的示例中,设置的值可以是一个
CmdId
,以确定要调用哪个回调。

我的初始响应是,如果现在已经有了,s就是您想要的。然而,你已经标记了它,因此你将不得不将就

基本上,您将a传递给要传递到
asio
的任务,但事先调用
get\u future
,并存储
future
值,该值与
promise
共享状态。任务完成后,您可以调用
promise::set_value
。在另一个线程中,您可以通过调用
future::is_ready
(非阻塞)或
future::wait
(阻塞)来检查是否发生了这种情况,然后在调用相应的回调函数之前从中检索值


e、 g.在您的示例中,该值集可以是一个
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);
        }
    };
class命令队列
{
公众:
void handle_命令(CmdId,int param)
{
io_service.post(boost::bind(&CommandQueue::DispatchCommand,this,id,param));
}
私人:
boost::asio::io_服务io_服务;
asio::io_服务::工作;
std::map dispatch_map;//CommandHandler是接受int参数的函子
CallbackSite callback\u站点;
void DispatchCommand(CmdId,int参数)
{
//当一个工作线程以该项开始时,我想调用
回调_site.cmd_已启动(id,param);
调度映射[id](参数);
//当命令函子返回且线程完成时
回调_site.cmd_已完成(id,param);
}
};

这也是我在处理已调度命令中的异常时使用的模式。您还可以发布不同的事件,而不是以内联方式运行它们。

因此,您想要的是在其中一个
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);
        }
    };
class命令队列
{
公众:
void handle_命令(CmdId,int param)
{
io_service.post(boost::bind(&CommandQueue::DispatchCommand,this,id,param));
}
私人:
boost::asio::io_服务io_服务;
asio::io_服务::工作;
std::map dispatch_map;//CommandHandler是接受int参数的函子
CallbackSite callback\u站点;
void DispatchCommand(CmdId,int参数)
{
//当一个工作线程以该项开始时,我想调用
回调_site.cmd_已启动(id,param);
调度映射[id](参数);
//当命令函子返回且线程完成时
回调_site.cmd_已完成(id,param);
}
};

这也是我在处理已调度命令中的异常时使用的模式。您还可以发布不同的事件,而不是内联运行它们。

用例?在我编译答案之前,在我看来,您似乎想要调度一个使用大量线程的命令,然后阻塞直到完成为止?@IdeaHat有一个异步命令源。有些命令比其他命令花费更多的时间。我想实现一个接收这些命令的非阻塞队列,几个线程将异步执行它们(1个线程上1个命令)。池中当前有4个工作线程。如果所有工作线程都在运行,那么该命令将添加到队列中(据我所知,
post
就是这样做的)。我是Asio新手,所以我的实现可能