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

How to call a function when a work item is finished in Boost.Asio?

本文关键字:工作 调用 函数 Boost Asio      更新时间:2023-10-16

我想实现一个命令队列,它与线程池同时处理传入的命令(因此当所有线程都在工作时,队列会暂时增长)。我想在命令工作者启动和完成时向调用方发布回调。我的实现基于 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);
        }
    };

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

相关文章: