Skip to content

Instantly share code, notes, and snippets.

@vermiculus
Last active August 29, 2015 14:07
Show Gist options
  • Save vermiculus/6214721463c7637a1bea to your computer and use it in GitHub Desktop.
Save vermiculus/6214721463c7637a1bea to your computer and use it in GitHub Desktop.
// -*- 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