Skip to content

Instantly share code, notes, and snippets.

@socantre
Created June 17, 2013 16:59
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 socantre/5798407 to your computer and use it in GitHub Desktop.
Save socantre/5798407 to your computer and use it in GitHub Desktop.
Example of semaphore using c++11 condition variables
#include <iostream>
#include <future>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>
#include <array>
#include <chrono>
int fib(int n) {
if (n<1) return 1;
return fib(n-1) + fib(n-2);
}
class Semaphore {
private:
std::mutex m;
std::condition_variable cv;
unsigned int count;
public:
Semaphore(int n) : count{n} {}
void notify() {
std::unique_lock<std::mutex> l(m);
++count;
cv.notify_one();
}
void wait() {
std::unique_lock<std::mutex> l(m);
cv.wait(l, [this]{ return count!=0; });
--count;
}
};
class Semaphore_waiter_notifier {
Semaphore &s;
public:
Semaphore_waiter_notifier(Semaphore &s) : s{s} { s.wait(); }
~Semaphore_waiter_notifier() { s.notify(); }
};
Semaphore thread_limiter{4};
std::mutex cout_mutex;
int main() {
std::vector<int> input(100);
std::array<int, 4> x {10, 35, 36, 40};
for (int i=0; i<input.size(); ++i) {
input[i] = x[i%x.size()];
}
auto start = std::chrono::high_resolution_clock::now();
std::vector<std::future<int>> output;
for (int i=0; i<input.size(); ++i) {
output.push_back(std::async([&input](int i)->int{
Semaphore_waiter_notifier w(thread_limiter);
(std::lock_guard<std::mutex>(cout_mutex), std::cout) << "\t\t\tstarting task: " << i << '\n';
auto result = fib(input[i]);
(std::lock_guard<std::mutex>(cout_mutex), std::cout) << "\t\t\t\t\t\ttask " << i << " finished\n";
return result;
}, i));
}
for (int i=0; i<output.size(); ++i) {
(std::lock_guard<std::mutex>(cout_mutex), std::cout) << "Waiting on task " << i << ".\n";
auto result = output[i].get();
(std::lock_guard<std::mutex>(cout_mutex), std::cout) << "\t\t\t\t\t\t\t\t\tTask " << i << " result: " << result << '\n';
}
auto end = std::chrono::high_resolution_clock::now();
std::cout << "total time: " << std::chrono::duration_cast<std::chrono::microseconds>(end-start).count() << "ms\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment