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

问题描述 投票:0回答:1

假设一个线程正在运行 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/async.html#c.uv_async_t精神的功能,在libuv中,通过

uv_async_send
这些保证是可能的:

  • 异步句柄允许用户“唤醒”事件循环并获取 从另一个线程调用的回调。

  • 从任何线程调用此函数都是安全的。回调将是 调用循环线程。

  • uv_async_send() 是异步信号安全的。调用这个函数是安全的 来自信号处理程序。

asio 中的等价物是什么?

c++ multithreading boost-asio
1个回答
0
投票

在 Asio 中,您将[1] 工作发布给执行者。

执行器与执行上下文相关联。在您的示例中,

io_context
就是这样一个执行上下文。

所以,你会说:

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

ADL 使得您可以使用不合格的:

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

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

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

差异

如果您使用

asio::dispatch
发布的处理程序可能会在调用线程上调用iff执行器与该线程匹配。例如。在给定的示例中 asio::dispatch
 的行为就像 
asio::post
 除非您从已经在“服务线程”(运行 io 上下文的线程)上运行的处理程序内部使用它。

相关执行者

执行者有多种类型。他们可能会添加自定义行为。例如,

strand<>

执行器确保只有一个处理程序同时运行,使您能够获得类似于同步代码中的互斥的访问序列化。

按理说,执行者的选择对于该机制的正确性至关重要。该库具有“关联执行器”功能,使其能够在通用代码中正确满足执行器要求。

例如,组合操作(如

asio::async_read_until

)将正确使用关联的执行器,即使对于它内部发布的任何中间处理程序也是如此。

要关联执行者,请使用

bind_executor

,例如:

asio::thread_pool tp; // multi threading execution context auto strand = make_strand(tp.get_executor()); // using a strand to serialize handlers auto handler = [] { std::cout << “On the strand: “ << strand.running_in_this_thread(); }; auto bound = bind_executor(strand, handler); // Now even posting _without_ an executor will invoke the bound handler on the intended executor: asio::post(bound);
更多相关信息请参阅:

  • boost::asio::bind_executor不在strand中执行
  • 将对象的所有异步操作放入 boost::asio::strand 的正确方法
  • std::boost::asio::post/dispatch 使用哪个io_context?
  • 当使用带有执行器参数的重载时,boost::asio 的 post 和dispatch 有什么区别?
更多与库的核心执行保证相关:

  • ASIO:是否定义了在不同线程中运行完成处理程序的行为?
[1]

asio::post

asio::defer
asio::dispatch

    

© www.soinside.com 2019 - 2024. All rights reserved.