24#include <unordered_set>
27namespace MultiProcess {
92 pid_t child_pid = fork();
94 while (child_pid == -1) {
97 printf(
"fork returned with error number %d, retrying after 1 second...\n", errno);
101 printf(
"fork returned with error number %d\n", errno);
102 throw std::runtime_error(
"fork returned with error 3 times, aborting!");
121 for (std::size_t ix = 0; ix <
N_workers_; ++ix) {
149 memset(&sa,
'\0',
sizeof(sa));
152 if (sigaction(SIGTERM, &sa,
nullptr) < 0) {
153 std::perror(
"sigaction failed");
159#if defined(__APPLE__)
161 static bool affinity_warned =
false;
163 std::cout <<
"CPU affinity cannot be set on macOS" << std::endl;
164 affinity_warned =
true;
170 std::cerr <<
"WARNING: CPU affinity setting not implemented on Windows, continuing..." << std::endl;
185 CPU_SET(set_cpu, &
mask);
188 if (sched_setaffinity(0,
sizeof(
mask), &
mask) == -1) {
189 std::cerr <<
"WARNING: Could not set CPU affinity, continuing..." << std::endl;
191 std::cerr <<
"CPU affinity set to cpu " << set_cpu <<
" in process " << getpid() << std::endl;
216 }
catch (
const std::exception &
e) {
217 std::cerr <<
"WARNING: something in ProcessManager::terminate threw an exception! Original exception message:\n"
218 <<
e.what() << std::endl;
237 }
while (-1 == pid && EINTR == errno);
240 if (WIFEXITED(status)) {
241 printf(
"exited, status=%d\n", WEXITSTATUS(status));
242 }
else if (WIFSIGNALED(status)) {
243 if (WTERMSIG(status) != SIGTERM) {
244 printf(
"killed by signal %d\n", WTERMSIG(status));
246 }
else if (WIFSTOPPED(status)) {
247 printf(
"stopped by signal %d\n", WSTOPSIG(status));
248 }
else if (WIFCONTINUED(status)) {
249 printf(
"continued\n");
254 if (errno == ECHILD) {
255 printf(
"chill_wait: no children (got ECHILD error code from wait call), done\n");
257 throw std::runtime_error(std::string(
"chill_wait: error in wait call: ") + strerror(errno) +
258 std::string(
", errno ") + std::to_string(errno));
273 std::unordered_set<pid_t> children;
278 children.insert(pid);
281 while (!children.empty()) {
321 printf(
"I'm a worker, PID %d\n", getpid());
323 printf(
"I'm master, PID %d\n", getpid());
325 printf(
"I'm queue, PID %d\n", getpid());
327 printf(
"I'm not master, queue or worker, weird! PID %d\n", getpid());
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
R__EXTERN C unsigned int sleep(unsigned int seconds)
ZeroMQSvc & zmqSvc()
Get singleton object of this class.
static bool getTimingAnalysis()
void initialize_processes(bool cpu_pinning=true)
Fork processes and activate CPU pinning.
std::vector< pid_t > worker_pids_
std::size_t N_workers() const
static void handle_sigterm(int signum)
We need this to tell the children to die, because we can't talk to them anymore during JobManager des...
bool is_initialized() const
static bool sigterm_received()
void wait_for_sigterm_then_exit()
void identify_processes() const
Print to stdout which type of process we are on and what its PID is (for debugging)
void terminate() noexcept
Shutdown forked processes if on master and if this process manager is initialized.
ProcessManager(std::size_t N_workers)
void shutdown_processes()
Shutdown forked processes if on master.
static volatile sig_atomic_t sigterm_received_
std::size_t worker_id() const
static void setup(pid_t proc, bool set_begin=true)
void close_context() const
pid_t fork_and_handle_errors()
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...