在协同程序执行之间强制执行睡眠

时间:2016-04-11 00:25:00

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

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

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

(因为我不希望任何线程转移,似乎我应该直接使用coroutine API而不是使用ASIO包装器或类似的,但我愿意被说服否则。我也使用Boost 1.55目前,光纤库不可用;但对于这种用途来说似乎也有点过头了。)

目前关于协同程序的主要问题是我不确定如何在轮询上实施限制 - 比如我有100个并行运行的任务;我希望它在所有100个任务中执行一次轮询,然后将线程休眠一段指定的时间。有些任务可能比其他任务更快完成,因此稍后它可能仍然会在每个循环中轮询40个任务,然后在相同的时间内休眠。我不希望它连续两次轮询相同的任务而没有干预睡眠。

1 个答案:

答案 0 :(得分:0)

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

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制作void (yield_context&),然后run_all lambda函数。第一个用于顶层,第二个用于嵌套协程。

似乎工作,虽然我还没有给它一个重要的锻炼。实际上有点惊讶这样的东西已不在图书馆了。