Skip to content

Commit 1ec5d07

Browse files
Add graceful shutdown example (#84)
1 parent ef127e6 commit 1ec5d07

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
install
44
docs
55
.cache
6+
*.profraw

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ DOCS_DIR = docs
77
all:
88

99
bench:
10+
# If needed: sudo cpupower frequency-set --governor <performance|powersave>
1011
mkdir -p $(BENCH_DIR) && cd $(BENCH_DIR) \
1112
&& cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCPP_CHANNEL_BUILD_BENCHMARKS=ON \
1213
&& cmake --build . --config Release --target channel_benchmark -j \

examples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@ run_example(example_concurrent_map_filter)
3737

3838
add_example(example_semaphore semaphore.cpp)
3939
run_example(example_semaphore)
40+
41+
add_example(example_graceful_shutdown graceful_shutdown.cpp)

examples/graceful_shutdown.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <msd/channel.hpp>
2+
3+
#include <atomic>
4+
#include <chrono>
5+
#include <csignal>
6+
#include <future>
7+
#include <iostream>
8+
#include <sstream>
9+
#include <thread>
10+
11+
static std::atomic<bool> shutdown{false};
12+
13+
void handle_sigint(int)
14+
{
15+
std::cout << "Waiting for channel to drain...\n";
16+
shutdown.store(true, std::memory_order_seq_cst);
17+
}
18+
19+
// Graceful shutdown using a bounded thread-safe channel. It runs a producer that sends integers and a consumer that
20+
// processes them. On Ctrl+C, it stops producing, closes the channel, and waits for the consumer to drain remaining
21+
// messages before exiting.
22+
23+
int main()
24+
{
25+
std::signal(SIGINT, handle_sigint);
26+
27+
msd::channel<int> channel{10};
28+
29+
// Continuously read from channel until it's drained (closed and empty)
30+
const auto consume = [&channel]() {
31+
for (const int message : channel) {
32+
std::stringstream stream;
33+
stream << message << " (" << channel.size() << ")\n";
34+
35+
std::cout << stream.str();
36+
37+
std::this_thread::sleep_for(std::chrono::milliseconds{100});
38+
}
39+
};
40+
41+
const auto consumer = std::async(consume);
42+
43+
// Continuously write to channel until process shutdown is requested
44+
const auto produce = [&channel]() {
45+
static int inc = 0;
46+
47+
while (!shutdown.load(std::memory_order_seq_cst)) {
48+
++inc;
49+
channel << inc;
50+
}
51+
52+
channel.close();
53+
};
54+
55+
const auto producer = std::async(produce);
56+
57+
// Wait
58+
consumer.wait();
59+
producer.wait();
60+
}

0 commit comments

Comments
 (0)