Joh*_*itb 6 c++ boost asynchronous boost-asio c++20
在以下示例中,计时器与 io_context 执行器关联。但随后,处理程序被告知在线程池中执行。原因是,因为处理程序实际上执行的是阻塞代码,而我不想阻塞runio_context的函数。
但文档指出
处理程序仅由当前正在为 io_context 调用 run()、run_one()、run_for()、run_until()、poll() 或 poll_one() 的任何重载的线程调用。
如代码所示,处理程序由 thread_pool 在run. 这种行为定义明确吗?它也适用于套接字吗?
#include <boost/asio.hpp>
#include <iostream>
int main() {
using namespace boost::asio;
thread_pool tp(4);
io_context ioc;
deadline_timer dt(ioc, boost::posix_time::milliseconds(500));
dt.async_wait(bind_executor(tp, [&](boost::system::error_code){
std::cout << "running in tp: " << tp.get_executor().running_in_this_thread() << std::endl;
std::cout << "running in ioc: " << ioc.get_executor().running_in_this_thread() << std::endl;
exit(0);
}));
auto wg = make_work_guard(ioc);
ioc.run();
}
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)running in tp: 1 running in ioc: 0
神箭链接。
首先要事。
您可以在任何您想要的地方运行处理程序。是否导致UB取决于您在处理程序中执行的操作。
我将您的问题解释为询问“观察到的行为是否与处理程序调用的记录要求/保证相矛盾?”
它不是。
您有两个不同的执行上下文。其中之一是io_context(您链接到其文档),另一个是thread_pool.
您要求调用处理程序tp(通过将处理程序绑定到其执行程序)。
deadline_timer因此,构造时绑定的默认执行程序将被处理程序的关联执行程序否决。
通过查看不管辖这种情况的文档,您会感到困惑io_context:截止日期计时器的完成从未发布到io_context. thread_pool根据您的具体要求,它会发布到 的上下文中。
正如预期的那样,处理程序在运行执行上下文的tp线程上调用。
这是一个直接使用的简化示例post,而不是通过任意异步启动函数来执行此操作。
此外,它还执行目标执行器和关联执行器(如果有)的所有组合。
#include <boost/asio.hpp>
#include <iomanip>
#include <iostream>
namespace asio = boost::asio;
int main() {
std::cout << std::boolalpha << std::left;
asio::io_context ioc;
asio::thread_pool tp(4);
auto xioc = ioc.get_executor();
auto xtp = tp.get_executor();
static std::mutex mx; // prevent jumbled output
auto report = [=](char const* id, auto expected) {
std::lock_guard lk(mx);
std::cout << std::setw(11) << id << " running in tp/ioc? "
<< xtp.running_in_this_thread() << '/'
<< xioc.running_in_this_thread() << " "
<< (expected.running_in_this_thread() ? "Ok" : "INCORRECT")
<< std::endl;
};
asio::post(tp, [=] { report("direct tp", xtp); });
asio::post(ioc, [=] { report("direct ioc", xioc); });
asio::post(ioc, bind_executor (tp, [=] { report("bound tp.A", xtp); }));
asio::post(tp, bind_executor (tp, [=] { report("bound tp.B", xtp); }));
asio::post( bind_executor (tp, [=] { report("bound tp.C", xtp); }));
asio::post(ioc, bind_executor (ioc, [=] { report("bound ioc.A", xioc); }));
asio::post(tp, bind_executor (ioc, [=] { report("bound ioc.B", xioc); }));
asio::post( bind_executor (ioc, [=] { report("bound ioc.C", xioc); }));
// system_executor doesn't have .running_in_this_thread()
// asio::post([=] { report("system", asio::system_executor{}); });
ioc.run();
tp.join();
}
Run Code Online (Sandbox Code Playgroud)
打印例如
direct tp running in tp/ioc? true/false Ok
direct ioc running in tp/ioc? false/true Ok
bound tp.C running in tp/ioc? true/false Ok
bound tp.B running in tp/ioc? true/false Ok
bound tp.A running in tp/ioc? true/false Ok
bound ioc.C running in tp/ioc? false/true Ok
bound ioc.B running in tp/ioc? false/true Ok
bound ioc.A running in tp/ioc? false/true Ok
Run Code Online (Sandbox Code Playgroud)
注意
有关语义,请post参阅文档或例如何时必须将 io_context 传递给 boost::asio::spawn?(C++)
| 归档时间: |
|
| 查看次数: |
941 次 |
| 最近记录: |