diff --git a/.gitignore b/.gitignore index d5180b2..d3f8fa8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ install docs .cache +*.profraw diff --git a/Makefile b/Makefile index 92d13b0..86ba8b9 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ DOCS_DIR = docs all: bench: + # If needed: sudo cpupower frequency-set --governor mkdir -p $(BENCH_DIR) && cd $(BENCH_DIR) \ && cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCPP_CHANNEL_BUILD_BENCHMARKS=ON \ && cmake --build . --config Release --target channel_benchmark -j \ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e664ef3..6ddde1d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,3 +37,5 @@ run_example(example_concurrent_map_filter) add_example(example_semaphore semaphore.cpp) run_example(example_semaphore) + +add_example(example_graceful_shutdown graceful_shutdown.cpp) diff --git a/examples/graceful_shutdown.cpp b/examples/graceful_shutdown.cpp new file mode 100644 index 0000000..5465190 --- /dev/null +++ b/examples/graceful_shutdown.cpp @@ -0,0 +1,60 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +static std::atomic shutdown{false}; + +void handle_sigint(int) +{ + std::cout << "Waiting for channel to drain...\n"; + shutdown.store(true, std::memory_order_seq_cst); +} + +// Graceful shutdown using a bounded thread-safe channel. It runs a producer that sends integers and a consumer that +// processes them. On Ctrl+C, it stops producing, closes the channel, and waits for the consumer to drain remaining +// messages before exiting. + +int main() +{ + std::signal(SIGINT, handle_sigint); + + msd::channel channel{10}; + + // Continuously read from channel until it's drained (closed and empty) + const auto consume = [&channel]() { + for (const int message : channel) { + std::stringstream stream; + stream << message << " (" << channel.size() << ")\n"; + + std::cout << stream.str(); + + std::this_thread::sleep_for(std::chrono::milliseconds{100}); + } + }; + + const auto consumer = std::async(consume); + + // Continuously write to channel until process shutdown is requested + const auto produce = [&channel]() { + static int inc = 0; + + while (!shutdown.load(std::memory_order_seq_cst)) { + ++inc; + channel << inc; + } + + channel.close(); + }; + + const auto producer = std::async(produce); + + // Wait + consumer.wait(); + producer.wait(); +}