mirror of
https://gitlab.com/niansa/libcrosscoro.git
synced 2025-03-06 20:53:32 +01:00
* 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
74 lines
2.2 KiB
C++
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)));
|
|
}
|