如何使用 boost::asio 对象中的执行程序将内容分派到同一个执行线程中?

How to use an executor from a boost::asio object to dispatch stuff into the same execution thread?

好的,我还没有足够的代码来开发一个完整的程序,但我已经 运行 遇到了“执行程序”的问题。

编辑:这是 Boost 1.74——Debian 没有给我任何更新的信息。这会在其他地方引起问题,但我希望它当时也有工作执行者:-)

按照其中一个野兽示例,我将“strand”分配给多个对象(一个解析器和一个流),以便在我需要采用多线程路由时更具前瞻性。但这实际上不是这里的问题,这只是我使用链的原因。

现在,我有这个对象,它有许多 asio“子对象”,它们都是用那个执行程序初始化的。那里没有问题,至少在编译器方面(我不知道代码是否完成了预期的事情......不过它在很大程度上基于一个野兽示例,所以它不是完全随机的)。

所以,我现在想向那个对象发送数据。这里的假设是,如果我只是从“外部”随机操作东西,那么整个执行器的东西是没有意义的,所以我想“分发”我对执行器的更改,以便它与可能正在进行的异步操作很好地配合,尤其是 when/if 线程发挥作用。而且由于所有 asio 对象都知道它们的执行者,所以我想我自己不需要记住它。

这里是一些随机的独立示例,显示了我遇到的问题。

#include <boost/asio.hpp>

/************************************************************************/

class Test
{
private:
    boost::asio::ip::tcp::resolver resolver;

public:
    Test(boost::asio::any_io_executor executor)
        : resolver(executor)
    {
    }

public:
    void doSomething()
    {
        std::function<void(void)> function;

        // Doesn't compile: no "dispatch" member
        resolver.get_executor().dispatch(function);

        // Doesn't compile: "target" is a template, needs a type
        resolver.get_executor().target()->dispatch(function);

        // Compiles, but I don't like having to know that it's a strand?
        // How can the asio objects use the executor without me telling them the type?
        // NOTE: I don't know whether it does the right thing!
        resolver.get_executor().target<boost::asio::io_context::strand>()->dispatch(function);
    }
};

/************************************************************************/

void test()
{
    boost::asio::io_context ioContext;

    Test test(boost::asio::make_strand(ioContext));
}

实际上都在“doSomething()”函数中:我如何将某些内容“分发”到某个 asio 对象使用的同一执行程序,而不必确切知道该执行程序是什么?

是的,我可以解决这个问题并传递“strand”对象而不是 any_executor,并将其与其他内容一起存储,以便我可以直接调用。但是因为每个 asio 对象都有一个执行器并且还设法正确使用它......我应该能够做同样的事情,不是吗?

Post, defer 和 dispatch 是免费函数:

boost::asio::dispatch(resolver.get_executor(), function);

直播:http://coliru.stacked-crooked.com/a/c39d263a99fbe3fd

#include <boost/asio.hpp>
#include <iostream>

struct Test {
  Test(boost::asio::any_io_executor executor) : resolver(executor) {}

  void doSomething() {
    boost::asio::dispatch(resolver.get_executor(), [] {std::cout << "Hello world\n";});
  }

private:
  boost::asio::ip::tcp::resolver resolver;
};

int main() {
  boost::asio::io_context ioContext;

  Test test(make_strand(ioContext));
  test.doSomething();
  ioContext.run();
}

版画

Hello world