Skip to content

Instantly share code, notes, and snippets.

@olned
Last active November 12, 2020 15:47
Show Gist options
  • Save olned/32abe1b1b37c7090f06c04a5d625e60d to your computer and use it in GitHub Desktop.
Save olned/32abe1b1b37c7090f06c04a5d625e60d to your computer and use it in GitHub Desktop.
SignalHandler Singleton C++
class SignalHandler {
public:
using Handler = std::function<void(int)>;
SignalHandler(const SignalHandler &) = delete;
SignalHandler &operator=(const SignalHandler) = delete;
static void process(int sig)
{
for (const auto &f : handler().handlers_)
f(sig);
}
static SignalHandler &handler()
{
static SignalHandler handler;
return handler;
}
static void push(Handler h)
{
handler().handlers_.emplace_back(h);
}
private:
SignalHandler(){};
std::vector<Handler> handlers_;
};
#include "signal_handler.hpp"
#include <chrono>
#include <csignal>
#include <iostream>
#include <stop_token>
#include <thread>
using namespace std::chrono_literals;
int next_id = 0;
void do_it(std::stop_token stop_token)
{
int no = next_id++;
std::cout << '#' << no << " do_it Start" << std::endl;
while (!stop_token.stop_requested()) {
std::this_thread::sleep_for(300ms);
}
std::cout << '#' << no << " do_it Exit" << std::endl;
}
int main(int argc, const char **argv)
{
const int num_channels = argc < 2 ? 2 : atoi(argv[1]);
std::vector<std::jthread> threads;
SignalHandler::push([&threads](int sig) {
for (auto &t : threads) {
t.request_stop();
}
});
std::signal(SIGINT, SignalHandler::process);
for (int i = 0; i < num_channels; ++i) {
std::this_thread::sleep_for(110ms);
threads.emplace_back(do_it);
}
for (auto &t : threads)
t.join();
return 0;
}
@olned
Copy link
Author

olned commented Nov 12, 2020

g++-10 src/test_handler.cpp -std=c++20 -lpthread && ./a.out 5 && rm ./a.out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment