1
0
Fork 0
mirror of https://gitlab.com/niansa/libcrosscoro.git synced 2025-03-06 20:53:32 +01:00
libcrosscoro/examples/coro_ring_buffer.cpp
Josh Baldwin fab634154f
Update README with section links (#70)
* Update README with section links

* add # to links

* try event instead of coro::event

* Update section names to remove "::" since markdown doesn't seem to link
properly with them
2021-02-27 12:33:42 -07:00

74 lines
2.2 KiB
C++

#include <coro/coro.hpp>
#include <iostream>
int main()
{
const size_t iterations = 100;
const size_t consumers = 4;
coro::thread_pool tp{coro::thread_pool::options{.thread_count = 4}};
coro::ring_buffer<uint64_t, 16> rb{};
coro::mutex m{};
std::vector<coro::task<void>> tasks{};
auto make_producer_task = [&]() -> coro::task<void> {
co_await tp.schedule();
for (size_t i = 1; i <= iterations; ++i)
{
co_await rb.produce(i);
}
// Wait for the ring buffer to clear all items so its a clean stop.
while (!rb.empty())
{
co_await tp.yield();
}
// Now that the ring buffer is empty signal to all the consumers its time to stop. Note that
// the stop signal works on producers as well, but this example only uses 1 producer.
{
auto scoped_lock = co_await m.lock();
std::cerr << "\nproducer is sending stop signal";
}
rb.stop_signal_notify_waiters();
co_return;
};
auto make_consumer_task = [&](size_t id) -> coro::task<void> {
co_await tp.schedule();
try
{
while (true)
{
auto value = co_await rb.consume();
{
auto scoped_lock = co_await m.lock();
std::cout << "(id=" << id << ", v=" << value << "), ";
}
// Mimic doing some work on the consumed value.
co_await tp.yield();
}
}
catch (const coro::stop_signal&)
{
auto scoped_lock = co_await m.lock();
std::cerr << "\nconsumer " << id << " shutting down, stop signal received";
}
co_return;
};
// Create N consumers
for (size_t i = 0; i < consumers; ++i)
{
tasks.emplace_back(make_consumer_task(i));
}
// Create 1 producer.
tasks.emplace_back(make_producer_task());
// Wait for all the values to be produced and consumed through the ring buffer.
coro::sync_wait(coro::when_all(std::move(tasks)));
}