C++11 并发编程教程 - Part 3 : 锁的进阶与条件变量

```struct Complex {
std::mutex mutex;
int i;
Complex() : i(0) {}
void mul(int x){
std::lock_guard<std::mutex> lock(mutex);
i *= x;
}
void div(int x){
std::lock_guard<std::mutex> lock(mutex);
i /= x;
}
};```

```void both(int x, int y){
std::lock_guard<std::mutex> lock(mutex);
mul(x);
div(y);
}```

```int main(){
Complex complex;
complex.both(32, 23);
return 0;
}```

```struct Complex {
std::recursive_mutex mutex;
int i;
Complex() : i(0) {}
void mul(int x){
std::lock_guard<std::recursive_mutex> lock(mutex);
i *= x;
}
void div(int x){
std::lock_guard<std::recursive_mutex> lock(mutex);
i /= x;
}
void both(int x, int y){
std::lock_guard<std::recursive_mutex> lock(mutex);
mul(x);
div(y);
}
};```

```std::timed_mutex mutex;
void work(){
std::chrono::milliseconds timeout(100);
while(true){
if(mutex.try_lock_for(timeout)){
std::cout << std::this_thread::get_id() << ": do work with the mutex" << std::endl;
std::chrono::milliseconds sleepDuration(250);
mutex.unlock();
} else {
std::cout << std::this_thread::get_id() << ": do work without mutex" << std::endl;
std::chrono::milliseconds sleepDuration(100);
}
}
}
int main(){
t1.join();
t2.join();
return 0;
}```

（这个示例在实践中是毫无用处的）

Call Once

```std::once_flag flag;
void do_something(){
std::call_once(flag, [](){std::cout << "Called once" << std::endl;});
std::cout << "Called each time" << std::endl;
}
int main(){
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}```

```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, [&count, &capacity](){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, [&count](){return count != 0; });
int result = buffer[front];
front = (front + 1) % capacity;
--count;
not_full.notify_one();
return result;
}
};```

```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;
}
}
void producer(int id, BoundedBuffer& buffer){
for(int i = 0; i < 75; ++i){
buffer.deposit(i);
std::cout << "Produced " << id << " produced " << i << std::endl;
}
}
int main(){
BoundedBuffer buffer(200);
c1.join();
c2.join();
c3.join();
p1.join();
p2.join();
return 0;
}```