| 10 | // Spawns multiple producers that send strings into a channel, which are streamed to std::cout from a consumer. |
| 11 | |
| 12 | int main() |
| 13 | { |
| 14 | using messages = msd::channel<std::string>; |
| 15 | |
| 16 | const auto threads = std::thread::hardware_concurrency(); |
| 17 | messages channel{threads}; |
| 18 | |
| 19 | // Continuously get some data on multiple threads and send it all to a channel |
| 20 | const auto produce = [](const std::size_t thread, const std::chrono::milliseconds pause, messages& chan) { |
| 21 | thread_local static std::size_t inc = 0U; |
| 22 | |
| 23 | while (!chan.closed()) { |
| 24 | ++inc; |
| 25 | chan << std::string{"Streaming " + std::to_string(inc) + " from thread " + std::to_string(thread)}; |
| 26 | |
| 27 | std::this_thread::sleep_for(pause); |
| 28 | } |
| 29 | }; |
| 30 | |
| 31 | std::vector<std::future<void>> producers; |
| 32 | for (std::size_t i = 0U; i < threads; ++i) { |
| 33 | producers.push_back(std::async(produce, i, std::chrono::milliseconds{500}, std::ref(channel))); |
| 34 | } |
| 35 | |
| 36 | // Close the channel after some time |
| 37 | const auto close = [](const std::chrono::milliseconds after, messages& chan) { |
| 38 | std::this_thread::sleep_for(after); |
| 39 | chan.close(); |
| 40 | }; |
| 41 | const auto closer = std::async(close, std::chrono::milliseconds{3000U}, std::ref(channel)); |
| 42 | |
| 43 | // Stream incoming messages |
| 44 | std::move(channel.begin(), channel.end(), std::ostream_iterator<std::string>(std::cout, "\n")); |
| 45 | |
| 46 | // Wait all tasks |
| 47 | for (auto& producer : producers) { |
| 48 | producer.wait(); |
| 49 | } |
| 50 | closer.wait(); |
| 51 | } |