Created
June 14, 2017 18:08
-
-
Save AlexDenisov/568bca211c24fcb5c5059699372e901e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.c | |
// processes | |
// | |
// Created by AlexDenisov on 14.06.17. | |
// Copyright © 2017 Low Level Bits. All rights reserved. | |
// | |
#include <assert.h> | |
#include <signal.h> | |
#include <unistd.h> | |
#include <iostream> | |
#include <chrono> | |
#include <thread> | |
using namespace std; | |
pid_t mullFork(const char *processName) { | |
static int childrenCount = 0; | |
childrenCount++; | |
const pid_t pid = fork(); | |
if (pid == -1) { | |
cout << "Failed to create " << processName | |
<< " after creating " << childrenCount | |
<< " child processes\n"; | |
cout << "Shutting down\n"; | |
exit(1); | |
} | |
return pid; | |
} | |
void do_fork() { | |
const pid_t watchdogPID = mullFork("watchdog"); | |
if (watchdogPID == 0) { | |
const pid_t timerPID = mullFork("timer"); | |
if (timerPID == 0) { | |
std::this_thread::sleep_for(std::chrono::seconds(5)); | |
exit(0); | |
} | |
const pid_t workerPID = mullFork("worker"); | |
if (workerPID == 0) { | |
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
exit(42); | |
} | |
int status = 0; | |
const pid_t exitedPID = waitpid(WAIT_ANY, &status, 0); | |
if (exitedPID == timerPID) { | |
/// Timer Process finished first, meaning that the worker timed out | |
kill(workerPID, SIGKILL); | |
cout << "Timed out\n"; | |
} else if (exitedPID == workerPID) { | |
kill(timerPID, SIGKILL); | |
/// Worker Process finished first | |
/// Need to check whether it has signaled (crashed) or finished normally | |
if (WIFSIGNALED(status)) { | |
cout << "Crashed\n"; | |
} | |
else if (WIFEXITED(status) && WEXITSTATUS(status) != 42) { | |
cout << "Abnormal Exit\n"; | |
} else { | |
cout << "All good\n"; | |
} | |
} else { | |
assert(0 && "Should not reach!"); | |
} | |
wait(nullptr); | |
exit(0); | |
} else { | |
pid_t pid = 0; | |
while ( (pid = waitpid(watchdogPID, 0, 0)) == -1 ) {} | |
} | |
wait(0); | |
} | |
int main(int argc, const char * argv[]) { | |
for (int i = 0; i < 10000; i++) { | |
cout << i << " "; | |
do_fork(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment