c++ 如何让asio eventloop从另一个线程调用lambda?

rqdpfwrv  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(114)

假设一个线程正在运行asio事件循环,我如何延迟在这个线程中调用lambda?

#include <thread>
#include <iostream>
#include <asio.hpp>

int main()
{
    asio::io_context io_context;
    // hook something into io_context
    std::jthread t([&]{io_context.run();});
    // now how to let eventoop thread call lambda
    io_context.async_call([]{std::cout<<"Hello World!";}); // this method does not exist
}

字符串
我正在寻找一个符合http://docs.libuv.org/en/v1.x/libuc.html#c.uv_libuc_t精神的功能,在libuv中,uv_async_send可以保证:

  • 异步句柄允许用户“唤醒”事件循环并从另一个线程获取回调。
  • 从任何线程调用此函数都是安全的。回调将在循环线程上调用。
  • uv_send_send()是一个信号安全的函数。从一个信号处理程序调用这个函数是安全的。

在asio中的等价物是什么?

o7jaxewo

o7jaxewo1#

在Asio中,您将[1]工作发布给执行人。
executor与执行上下文相关联。在您的示例中,io_context就是这样的执行上下文。
所以你会说

asio::post(io_context.get_executor(), []{std::cout<<"Hello World!";});

字符串
ADL使得你可以使用unqualified:

post(io_context.get_executor(), []{std::cout<<"Hello World!";});


接下来,为了方便起见,Asio支持发布“到”执行上下文,在这种情况下,将使用其默认执行器:

post(io_context, []{std::cout<<"Hello World!";});

差异

如果你使用asio::dispatch,posted处理程序**可能会在调用线程上被调用 * 当 * executor匹配那个线程时。例如,在给定的例子中,asio::dispatch的行为就像asio::post一样,除非你从一个已经在“服务线程”(一个运行io上下文的线程)上运行的处理程序内部使用它。

关联执行者

有多种类型的执行器。它们可能会添加自定义行为。例如,strand<>执行器确保只有一个处理程序并发运行,使您能够获得类似于同步代码中互斥的访问序列化。
显然,执行器的选择对于这个机制的正确性是很重要的,库有一个“关联执行器”的工具,允许它在泛型代码中正确地荣誉执行器需求。
例如,组合操作(如asio::async_read_until)将正确地使用关联的执行器,即使是它内部发布的任何中间处理程序。
要关联执行器,请使用bind_executor,例如:

Live On Colriu

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

int main() {
    boost::asio::thread_pool tp; // multi threading execution context
    auto strand = make_strand(tp.get_executor()); // using a strand to serialize handlers

    auto handler = [&strand] { std::cout << "On the strand: " << strand.running_in_this_thread() << std::endl; };
    auto bound = bind_executor(strand, handler);

    // Now even posting _without_ an executor will invoke the bound handler on the intended executor:
    post(bound);

    tp.join();
}


哪个指纹

On the strand: 1


有关更多相关信息,请参见:

更多关于库的核心执行保证:

[1]asio::postasio::deferasio::dispatch

相关问题