Consider a parallel program that consists of a number of worker threads. These threads have a poll-loop on some file descriptors. The program is supposed to run until ctrl-c is hit / the process receives a SIGINT. The program should never wake up unnecessarily.
I have devised the following combination of sigwait, std::thread, pipe and pthread_sigmask. Note that in the actual application, there are more file descriptors, hence I am not using atomics for shutting down the threads.
#include <thread>
#include <iostream>
#include <cstdlib>
#include <csignal>
extern "C" {
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <poll.h>
}
int fds[2];
void thread_run() {
struct pollfd pfd = {fds[0], POLLIN, 0};
int ret = poll(&pfd, 1, -1);
if (ret != 1) std::terminate();
if (!pfd.revents & POLLIN) std::abort();
}
int main()
{
int ret = pipe(fds);
if (ret) std::abort();
sigset_t ss;
sigemptyset(&ss);
sigaddset(&ss, SIGINT);
ret = pthread_sigmask(SIG_BLOCK, &ss, NULL);
if (ret) std::abort();
std::thread t(thread_run);
int sig;
ret = sigwait(&ss, &sig);
if (ret) std::abort();
char b = 0;
ret = write(fds[1], &b, 1);
if (ret != 1) std::abort();
t.join();
close(fds[0]);
close(fds[1]);
}
The program appears to work without any issues.
std::thread-creation and pthread_sigmask?You may like to use std::abort call for unexpected situations. std::terminate is called by the C++ runtime when exception handling fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With