diff --git a/README.md b/README.md index 97f268c..7c35e3c 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,88 @@ Signal handler that uses [pthread_sigmask](http://man7.org/linux/man-pages/man3/ int last_signal = signal_handler.sigwait_handler(handler); } // signals are unblocked again ``` -See [example.cpp](example/example.cpp) for an example using threads. + +Using a condition variable to shutdown all threads: + +```C++ +#include +#include + +#include +#include +#include +#include + + +void Worker(const sgnl::AtomicCondition& exit_condition) +{ + auto predicate = [&exit_condition]() { + return exit_condition.get(); + }; + while( true ) + { + exit_condition.wait_for(std::chrono::minutes(1), predicate); + if( exit_condition.get() ) + return; + /* ... do work ... */ + } +} + +int main() +{ + sgnl::AtomicCondition exit_condition(false); + + auto handler = [&exit_condition](int signum) { + std::cout << "received signal " << signum << "\n"; + if( signum == SIGTERM || signum == SIGINT ) + { + exit_condition.set(true); + // wakeup all waiting threads + exit_condition.notify_all(); + // stop polling for signals + return true; + } + + // continue waiting for signals + return false; + }; + + // Block signals in this thread. + // Threads spawned later will inherit the signal mask. + sgnl::SignalHandler signal_handler({SIGINT, SIGTERM, SIGUSR1}); + + std::future ft_sig_handler = + std::async( + std::launch::async, + &sgnl::SignalHandler::sigwait_handler, + &signal_handler, + std::ref(handler)); + + std::vector> futures; + for(int i = 0; i < 10; ++i) + futures.push_back( + std::async( + std::launch::async, + Worker, + std::ref(exit_condition))); + + // SIGUSR1 + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + kill(0, SIGUSR1); + + // SIGTERM + kill(0, SIGTERM); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + for(auto& future : futures) + future.wait(); + + int last_signal = ft_sig_handler.get(); + std::cout << "exiting (received signal " << last_signal << ")\n"; + + return EXIT_SUCCESS; +} +``` ## Build & Install