Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
August 14, 2022 02:46 pm GMT

The simplest example of coroutines in C20

The coroutines were introduced in C++20 standard. Unfortunately, the implementation isn't such friendly even for experienced programmers because the standard library provides only interfaces and leave the event loop, awaiters, promises etc. on programmers.

This is a minimal working example which could help people to start learning:

#include <iostream>#include <coroutine>#include <thread>#include <queue>#include <functional>std::queue<std::function<bool()>> task_queue;struct sleep {    sleep(int n) : delay{n} {}    constexpr bool await_ready() const noexcept { return false; }    void await_suspend(std::coroutine_handle<> h) const noexcept {        auto start = std::chrono::steady_clock::now();        task_queue.push([start, h, d = delay] {            if (decltype(start)::clock::now() - start > d) {                h.resume();                return true;            } else {                return false;            }        });    }    void await_resume() const noexcept {}    std::chrono::milliseconds delay;};struct Task {    struct promise_type {        promise_type() = default;        Task get_return_object() { return {}; }        std::suspend_never initial_suspend() { return {}; }         std::suspend_always final_suspend() noexcept { return {}; }        void unhandled_exception() {}    };};Task foo1() noexcept {    std::cout << "1. hello from foo1" << std::endl;    for (int i = 0; i < 10; ++i) {        co_await sleep{10};        std::cout << "2. hello from foo1" << std::endl;    }}Task foo2() noexcept {    std::cout << "1. hello from foo2" << std::endl;    for (int i = 0; i < 10; ++i) {        co_await sleep{10};        std::cout << "2. hello from foo2" << std::endl;    }}//call fooint main() {    foo1();    foo2();    while (!task_queue.empty()) {        auto task = task_queue.front();        if (!task()) {            task_queue.push(task);        }        task_queue.pop();        std::this_thread::sleep_for(std::chrono::milliseconds(10));    }}

The magic happens here co_await sleep{10};. The current coroutine suspends and the awaiter takes its handler to resume it later. In this example, the awaiter defers a task into an event loop to checks if the sleep time expires.

This is a simple event loop with a queue of tasks:

while (!task_queue.empty()) {    auto task = task_queue.front();    if (!task()) {        task_queue.push(task);    }    task_queue.pop();    std::this_thread::sleep_for(std::chrono::milliseconds(10));}

Play with this example a bit before starting to read about the coroutines in detail. Hope, it was helpful!


Original Link: https://dev.to/atimin/the-simplest-example-of-coroutines-in-c20-4l7a

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To