【问题标题】:Enforce sleep between coroutine executions在协程执行之间强制休眠
【发布时间】:2016-07-31 23:38:15
【问题描述】:

我目前有一些同步 C++ 代码,它们以顺序方式执行一些耗时的任务。我正在考虑使用 Boost 协程将其重构为并行任务。

任务的核心是调用外部库,该库提供同步 API(它当前正在使用)或异步 API,必须定期轮询以执行操作并确定操作是否已完成。该 API 不是线程安全的,但如果使用异步版本,只要轮询 API 本身不被并发调用,它就可以处理同时发生的多个请求。

(由于我不想要任何线程转移,看来我应该直接使用协程 API 而不是使用 ASIO 包装器或类似的,但我愿意被说服。我也在使用 Boost 1.55目前,Fiber 库不可用;但这种用法似乎也有点过头了。)

目前我对协程的主要问题是我不确定如何在轮询中实现节流——假设我有 100 个任务要并行运行;我希望它对所有 100 个任务进行一次轮询,然后让线程休眠指定的时间。一些任务可能比其他任务完成得更快,因此稍后它可能仍会在每个循环中轮询 40 个任务,然后休眠相同的时间。我不希望它在没有干预睡眠的情况下连续两次轮询同一任务。

【问题讨论】:

  • 那么是什么阻止您编写您所描述的内容?将协程编码为仅在它想休眠时才让出,然后运行所有活动的协程,休眠并重复。
  • 可能只是不熟悉。也许这比我想象的要简单。

标签: c++ asynchronous boost coroutine boost-coroutine


【解决方案1】:

好的,结果比我想象的要容易得多。到目前为止,这是我最终的结果:

typedef boost::coroutines::coroutine<void>::push_type coroutine;
typedef boost::coroutines::coroutine<void>::pull_type yield_context;
typedef std::vector<coroutine> coroutine_list;

bool run_once_all(coroutine_list& coros)
{
    bool pending = false;
    for (auto& coro : coros)
    {
        if (coro)
        {
            coro();
            pending = pending || !coro.empty();
        }
    }
    return pending;
}

void run_all(coroutine_list& coros,
             const boost::chrono::nanoseconds& idle_ns)
{
    while (run_once_all(coros))
    {
        boost::this_thread::sleep_for(idle_ns);
    }
}

void run_all(coroutine_list& coros, yield_context& yield)
{
    while (run_once_all(coros))
    {
        yield();
    }
}

这个想法是你创建一个coroutine_list,然后是emplace_back lambda 函数,签名为void (yield_context&amp;),然后是run_all。第一个用于顶层,第二个用于嵌套协程。

似乎工作,虽然我还没有给它一个大的锻炼呢。实际上有点惊讶,图书馆里还没有这样的东西。

【讨论】:

    猜你喜欢
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    相关资源
    最近更新 更多