http://baptiste-wicht.com/posts/2012/04/c11-concurrency-tutorial-advanced-locking-and-condition-variables.html
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
|
struct
BoundedBuffer {
int * buffer;
int
capacity;
int
front;
int
rear;
int
count;
std::mutex lock;
std::condition_variable not_full;
std::condition_variable not_empty;
BoundedBuffer( int
capacity) : capacity(capacity), front(0), rear(0), count(0) {
buffer = new
int [capacity];
}
~BoundedBuffer(){
delete [] buffer;
}
void
deposit( int
data){
std::unique_lock<std::mutex> l(lock);
not_full.wait(l, [ this ](){ return
count != capacity; });
buffer[rear] = data;
rear = (rear + 1) % capacity;
++count;
not_empty.notify_one();
}
int
fetch(){
std::unique_lock<std::mutex> l(lock);
not_empty.wait(l, [ this ](){ return
count != 0; });
int
result = buffer[front];
front = (front + 1) % capacity;
--count;
not_full.notify_one();
return
result;
}
}; |
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
|
#include <iostream> #include <thread> #include <mutex> #include <condition_variable> //using namespace std; void
consumer( int
id, BoundedBuffer& buffer){
for ( int
i = 0; i < 50; ++i){
int
value = buffer.fetch();
std::cout << "Consumer "
<< id << " fetched "
<< value << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(250));
}
} void
producer( int
id, BoundedBuffer& buffer){
for ( int
i = 0; i < 75; ++i){
buffer.deposit(i);
std::cout << "Produced "
<< id << " produced "
<< i << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
} int
main(){
BoundedBuffer buffer(200);
std:: thread
c1(consumer, 0, std::ref(buffer));
std:: thread
c2(consumer, 1, std::ref(buffer));
std:: thread
c3(consumer, 2, std::ref(buffer));
std:: thread
p1(producer, 0, std::ref(buffer));
std:: thread
p2(producer, 1, std::ref(buffer));
c1.join();
c2.join();
c3.join();
p1.join();
p2.join();
return
0;
} |