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

C++11 并发编程教程 - Part 3 : 锁的进阶与条件变量
• 发表于 4年前
• 阅读 236
• 收藏 5
• 评论 0

 1 2 3 4 5 6 7 8 9 10 11 12 13 struct  Complex {     std::mutex mutex;     int  i;     Complex() : i(0) {}     void  mul(int  x){         std::lock_guard lock(mutex);         i *= x;     }     void  div(int  x){         std::lock_guard lock(mutex);         i /= x;     } };

 1 2 3 4 5 void  both(int  x,  int  y){     std::lock_guard lock(mutex);     mul(x);     div(y); }

 1 2 3 4 5 int  main(){     Complex complex;     complex.both(32, 23);     return  0; }

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 struct  Complex {     std::recursive_mutex mutex;     int  i;     Complex() : i(0) {}     void  mul(int  x){         std::lock_guard lock(mutex);         i *= x;     }     void  div(int  x){         std::lock_guard lock(mutex);         i /= x;     }     void  both(int  x,  int  y){         std::lock_guard lock(mutex);         mul(x);         div(y);     } };

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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);             std::this_thread::sleep_for(sleepDuration);             mutex.unlock();             std::this_thread::sleep_for(sleepDuration);         }  else  {             std::cout << std::this_thread::get_id() <<  ": do work without mutex"  << std::endl;             std::chrono::milliseconds sleepDuration(100);             std::this_thread::sleep_for(sleepDuration);         }     } } int  main(){     std::thread  t1(work);     std::thread  t2(work);     t1.join();     t2.join();     return  0; }

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

Call Once

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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(){     std::thread  t1(do_something);     std::thread  t2(do_something);     std::thread  t3(do_something);     std::thread  t4(do_something);     t1.join();     t2.join();     t3.join();     t4.join();     return  0; }

 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 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 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 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;     } };

 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 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; }

×