Boost ASIO:通知所有待处理的任务

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

想象有 3 个任务注册到 ASIO

io_context
A、B 和 C。 A 现在可能正在运行,当它完成时,C 已经准备好运行,所以它确实可以运行,但即使完成时 B 还没有运行准备好。我希望能够注册一个处理程序,以便在当前没有任务能够取得进展的情况下调用。我正在构建的系统可以受益于本质上能够说“此时没有什么可做的,你有一些时间来执行更多计算密集型任务”。

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

我正在构建的系统可以受益于本质上能够说“此时没有什么可做的,你有一些时间来执行更多计算密集型任务”。

做到这一点的方法通常是拥有专用的任务队列,这样您就可以检测特定负载何时高、低甚至空闲。基本上,与 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 无堆栈协程,则可以使用并行组的语法糖,例如:

住在Coliru

#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

正如您所看到的,即使它全部面向异步操作,您已经可以使用它实现一些“高级”语义。

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