Reputation: 505
Since a C++ signal handler should only access volatile std::sig_atomic_t or std::atomic(since C++11), is it possible to have a thread sleeping and wake with it?
std::atomic_bool exit_now(false);
void signal_handler(int signal)
{
exit_now=true;
}
int main() {
std::signal(SIGINT, signal_handler);
A a;
B b;
a.RunAsync();
b.RunAsync();
while(!exit_now)
std::this_thread::sleep_for(std::chrono::seconds(1));
a.Stop();
b.Stop();
return 0;
}
In this case, A and B ::RunAsync() both do their business on other threads until I call ::Stop(), so my only option is to busy-wait on the main thread (with or without a predefined sleep period).
Ideally I would want the main thread to sleep until signaled, possibly with a condition variable, but that looks illegal to do.
Upvotes: 4
Views: 1172
Reputation: 115
What you're after is a way to wake up the thread in a manner that is async-signal-safe.
My preferred way of doing this in Linux is using POSIX semaphores. Bear in mind this might not be portable to other operating systems as POSIX semaphores are not required for an OS to be considered POSIX compliant.
// signalSemaphore is a global variable
if (sem_init(&signalSemaphore, 0, 0)) {
std::cerr << "Unable to initialise semaphore: " << strerror(errno);
return 1;
}
while(sem_wait(signalSemaphore)) {
if(errno != EINTR) {
// call can be interrupted, so if the error is EINTR we ignore it
std::cerr << "Error waiting for signal semaphore: " << strerror(errno);
}
}
sem_wait()
call:void signalHandler(int signal) {
sem_post(&signalSemaphore);
}
Alternatively, using pipes is also an option since the read()
and write()
syscalls are also async-signal-safe, and pipes is a more portable mechanism. See an example on how to do it here: How can I wake a thread in macOS in a way that is async-signal-safe?
Upvotes: 0
Reputation: 1351
I would suggest (blocking the signals and) using sigwait(2) to synchronously wait for the signals in the main thread, then you completely circumvent the issue of having to communicate from a signal handler to a thread.
Upvotes: 2