-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathsemaphore.cpp
More file actions
62 lines (47 loc) · 1.52 KB
/
semaphore.cpp
File metadata and controls
62 lines (47 loc) · 1.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <msd/channel.hpp>
#include <chrono>
#include <future>
#include <iostream>
#include <numeric>
#include <thread>
#include <vector>
class semaphore {
public:
explicit semaphore(std::size_t limit) : chan_{limit} {}
void acquire() { chan_ << empty_; }
void release() { chan_ >> empty_; }
private:
struct empty {};
msd::channel<empty> chan_;
empty empty_{}; // See EBO starting C++20: https://en.cppreference.com/w/cpp/language/ebo.html
};
int simulate_heavy_computation(const int value)
{
const int result = value * 2;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
return result;
};
// https://en.wikipedia.org/wiki/Semaphore_(programming)
int main()
{
semaphore sem{2};
std::vector<std::future<int>> futures;
for (int i = 1; i <= 10; ++i) {
const auto worker = [&sem](const int value) {
sem.acquire();
const int result = simulate_heavy_computation(value);
sem.release();
return result;
};
futures.push_back(std::async(worker, i));
}
std::cout << "Waiting for result...\n";
const int result = std::accumulate(futures.begin(), futures.end(), 0,
[](int acc, std::future<int>& future) { return acc + future.get(); });
std::cout << "Result is: " << result << '\n';
const int expected = 110;
if (result != expected) {
std::cerr << "Error: result is " << result << ", expected " << expected << '\n';
std::terminate();
}
}