Skip to content

Instantly share code, notes, and snippets.

@cwvh
Created January 8, 2013 19:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cwvh/4486887 to your computer and use it in GitHub Desktop.
Save cwvh/4486887 to your computer and use it in GitHub Desktop.
#include <exception>
#include <future>
#include <thread>
#include <tbb/concurrent_queue.h>
namespace {
template<typename Future, typename F, typename T>
void set_value(std::promise<Future>& p, F& f, T& t) {
p.set_value(f(t));
}
template<typename F, typename T>
void set_value(std::promise<void>& p, F& f, T& t) {
f(t);
p.set_value();
}
}
template<typename T>
class concurrent {
public:
concurrent(T t = T{})
: t{t}
, thrd{[=]{
while (!done) {
std::function<void()> f;
q.pop(f);
f();
}
}}
{ /* empty */ }
~concurrent() {
q.push([=]{ done = true; });
thrd.join();
}
template<typename F>
auto operator()(F f) const -> std::future<decltype(f(t))> {
auto p = std::make_shared<std::promise<decltype(f(t))>>();
auto r = p->get_future();
q.push([=]{
try { set_value(*p, f, t); }
catch(...) { p->set_exception(std::current_exception()); }
});
return r;
}
private:
/* mutable */ T t;
mutable tbb::concurrent_bounded_queue<std::function<void()>> q;
bool done = false;
std::thread thrd;
};
#include <iostream>
#include <vector>
#include "concurrent.hpp"
int main() {
using namespace std;
concurrent<ostream&> async_cout{cout};
vector<future<void>> v;
for (int i = 0; i < 5; i++) {
v.push_back(async([&, i]{
async_cout([=](ostream& cout){
cout << to_string(i) << " " << to_string(i);
cout << "\n";
});
async_cout([=](ostream& cout){
cout << "Hi from " << i << endl;
});
}));
}
for (auto& f : v)
f.wait();
cout << "Done\n";
async_cout([](ostream& cout){ cout << "Done\n"; });
/*
concurrent<string> s{"start\n"};
vector<future<void>> v;
for (int i = 0; i < 5; i++) {
v.push_back(async([&, i]{
s([=](string& s){
s += to_string(i) + " " + to_string(i);
s += "\n";
});
s([](string& s){
cout << s;
});
}));
}
for (auto& f : v)
f.wait();
cout << "Done\n";
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment