Last active
August 29, 2015 14:07
-
-
Save vermiculus/6214721463c7637a1bea to your computer and use it in GitHub Desktop.
This file contains 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
// -*- compile-command: "g++ -std=c++0x main.cpp;./a.out" -*- | |
#include <iostream> | |
#include <thread> | |
#include <map> | |
#include <unistd.h> | |
typedef char status_t; | |
/** | |
* I know I'm not supposed to be using system, but I don't know what | |
* else to use in this context. The program I'm starting is, | |
* theoretically, arbitrary. | |
* | |
* @param command a shell command to run, such as "pdflatex file.tex" | |
* @param running a sentinal boolean for whether this thread is still | |
* running | |
* @param exit_code_buf a buffer for the exit code | |
* | |
* @todo use std::{atomic,future,promise} appropriately... | |
*/ | |
void run(std::string command, bool *running, status_t *exit_code_buf) | |
{ | |
// TODO: add std::chrono::duration timeout | |
*running = true; | |
*exit_code_buf = system(command.c_str()); | |
*running = false; | |
} | |
class ProcessGroup | |
{ | |
std::map<std::pair<std::thread *, bool *>, status_t *> threads; | |
public: | |
void Add(std::string); | |
void Join(); | |
}; | |
/** | |
* Starts a process in a new thread and adds it to the map | |
* | |
* @param command a command to start | |
* | |
* @todo use std::{atomic,future,promise} appropriately... | |
*/ | |
void | |
ProcessGroup::Add(std::string command) | |
{ | |
status_t *status = new status_t(0); | |
bool *running = new bool(false); | |
std::thread *t = new std::thread(&run, command, running, status); | |
threads.insert(std::make_pair(std::make_pair(t, running), status)); | |
} | |
/** | |
* Periodically checks all threads to see if they are still running. | |
* If one of them is, sleep for a small amount of time and check | |
* again. | |
*/ | |
void | |
ProcessGroup::Join() | |
{ | |
bool still_running; | |
do { | |
still_running = false; | |
for (auto it = threads.cbegin(); it != threads.cend(); ++it) { | |
still_running |= *it->first.second; | |
} | |
std::cout << "checking" << std::endl; | |
if (still_running) usleep (100000); | |
} while (still_running); | |
} | |
int main() | |
{ | |
std::cout << "Program start." << std::endl; | |
ProcessGroup pg; | |
std::string | |
block("echo block; sleep 1; echo unblock"), | |
pass("echo pass"); | |
pg.Add(block); | |
std::cout << "here" << std::endl; | |
for (int i = 0; i<10; i++) { | |
pg.Add(pass); | |
} | |
std::cout << "Joining threads..." << std::endl; | |
pg.Join(); | |
std::cout << "Program end." << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment