1. 程式人生 > 實用技巧 >muduo原始碼解析7-countdownlatch類

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