想象有 3 个任务注册到 ASIO
io_context
A、B 和 C。 A 现在可能正在运行,当它完成时,C 已经准备好运行,所以它确实可以运行,但即使完成时 B 还没有运行准备好。我希望能够注册一个处理程序,以便在当前没有任务能够取得进展的情况下调用。我正在构建的系统可以受益于本质上能够说“此时没有什么可做的,你有一些时间来执行更多计算密集型任务”。
我正在构建的系统可以受益于本质上能够说“此时没有什么可做的,你有一些时间来执行更多计算密集型任务”。
做到这一点的方法通常是拥有专用的任务队列,这样您就可以检测特定负载何时高、低甚至空闲。基本上,与 Asio 无关,Asio 仅具有一个事件循环,其自己的队列与异步操作相关。
也就是说,您可以经常使用计时器作为事件,例如
asio::steady_timer t(ex, asio::steady_timer::time_point::max());
// when all tasks done, do
t.expires_at(asio::steady_timer::time_point::min());
此外,您还可以使用新的
parallel_group
功能:协调并行操作。请记住,当然,这仍然面向异步操作。
您没有指定您的代码使用什么完成机制,但如果您正在考虑使用 C++20 无堆栈协程,则可以使用并行组的语法糖,例如:
#include <boost/asio.hpp>
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <iostream>
namespace asio = boost::asio;
using namespace asio::experimental::awaitable_operators;
using namespace std::chrono_literals;
using tcp = asio::ip::tcp;
asio::awaitable<void> delay(auto duration) {
co_await asio::steady_timer( //
co_await asio::this_coro::executor, duration)
.async_wait(asio::deferred);
}
asio::awaitable<void> session(tcp::socket s) {
std::cout << "Accepted " << s.remote_endpoint() << " on " << s.local_endpoint() << std::endl;
auto upstream = []() -> asio::awaitable<void> { co_return; /* TODO */ };
auto downstream = []() -> asio::awaitable<void> { co_return; /* TODO */ };
co_await (upstream() && downstream());
}
asio::awaitable<void> listener(uint16_t port) {
auto ex = co_await asio::this_coro::executor;
tcp::acceptor acc(ex, {{}, port});
for(;;)
co_spawn(ex, session(co_await acc.async_accept(asio::deferred)), asio::detached);
}
int main() {
asio::thread_pool ioc(1);
asio::signal_set ss(ioc, SIGINT);
auto interrupted = ss.async_wait(asio::use_awaitable);
co_spawn(ioc,
(listener(8989) && listener(8443)) || delay(10s) || std::move(interrupted), //
asio::detached);
ioc.join();
}
具有在线输出:
g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp
./a.out&
(for a in {1..5}; do sleep 0.$RANDOM; netcat 127.0.0.1 8989 -w 0 <<< "HELLO"; done)&
(for a in {1..5}; do sleep 0.$RANDOM; netcat 127.0.0.1 8443 -w 0 <<< "HELLO"; done)&
time wait
Accepted 127.0.0.1:51650 on 127.0.0.1:8443
Accepted 127.0.0.1:51652 on 127.0.0.1:8443
Accepted 127.0.0.1:51654 on 127.0.0.1:8443
Accepted 127.0.0.1:51656 on 127.0.0.1:8443
Accepted 127.0.0.1:46716 on 127.0.0.1:8989
Accepted 127.0.0.1:51660 on 127.0.0.1:8443
Accepted 127.0.0.1:46720 on 127.0.0.1:8989
Accepted 127.0.0.1:46722 on 127.0.0.1:8989
Accepted 127.0.0.1:46726 on 127.0.0.1:8989
Accepted 127.0.0.1:46728 on 127.0.0.1:8989
real 0m10.006s
user 0m0.004s
sys 0m0.012s
正如您所看到的,即使它全部面向异步操作,您已经可以使用它实现一些“高级”语义。