muduo源码解析7-countdownlatch类

countdownlatch

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...

posted @ 2020-08-23 11:18  WoodInEast  阅读(243)  评论(0编辑  收藏  举报