class countdownlatch:noncopyable { };
countdownlatch和mutex,condition一样,用于线程之间的同步,主要用于这样一种情况:
有一组线程,计算线程,IO线程1,IO线程2,
我们规定计算线程必须在所有的IO线程都结束后才能执行。
如果单纯使用mutex,计算线程可能比其他IO线程先抢到mutex,这不符合计算线程最后执行的要求。
但是可以使用条件变量来完成,当然条件变量不能单独使用,需要配套一个mutex,计算线程必须在符合条件(IO1,IO2都完成)时才能获得锁。
countdownlatch就是使用条件变量来完成的,可以初始化一个countdownlatch(2),让IO1和IO2先执行,此时
countdownlatch内部m_count值为2,计算线程向要请求锁,但是条件变量不允许,因此m_count>0,只有当IO1和IO2都完成并对m_count--后,计算线程被唤醒,发现m_count==0才可以执行。
private: mutable mutexlock m_mutex; condition m_cond; int m_count;
分别表示:互斥锁mutex,条件变量condition和执行线程计数count
public: countdownlatch(int count):m_mutex(),m_cond(m_mutex),m_count(count){} //我们要同步的那一个线程,要执行时必须先wait,只有先决线程全结束后才可以执行 void wait() { mutexlockguard mlg(m_mutex); while(m_count>0) m_cond.wait(); } //先决线程执行完毕,让引用计数-- void countDown() { mutexlockguard mlg(m_mutex); m_count--; if(m_count==0) m_cond.notifyAll(); } //返回先决线程即引用计数的数量 int getCount() const { mutexlockguard mlg(m_mutex); return m_count; }
使用countdownlatch来测试上面的IO线程和计算线程同步的例子
#include"base/mutex.h" #include"base/condition.h" #include"base/countdownlatch.h" #include<thread> #include <stdio.h> #include<queue> #include<iostream> namespace mymuduo{ namespace currentthread { void cacheTid() { } } } //初始化m_count为2,表示有两个先决线程IO1和IO2 mymuduo::countdownlatch cdl(2); void IOThread() { //IO... 2s std::this_thread::sleep_for(std::chrono::milliseconds(2000)); std::cout<<"IO completed...\n"; cdl.countDown(); } void computeThread() { //等待IO1和IO2完成后才能执行 cdl.wait(); std::cout<<"computing...\n"; } int main() { std::thread t1,t2,t3; t1=std::thread(computeThread); t2=std::thread(IOThread); t3=std::thread(IOThread); t1.join();t2.join();t3.join(); }
计算结果:
不用想,computing...肯定在最后出现
IO completed...
IO completed...
computing...
原文:https://www.cnblogs.com/woodineast/p/13548639.html