(转载)CountDownLatch实现原理及使用

本文转载https://blog.csdn.net/zhangxiao93/article/details/72677207

CountDownLatch用于主线程等待工作线程完成工作,注意,这里与pthread_join不一样:

pthread_join是只要线程active就会阻塞,线程结束就会返回.一般用于主线程回收工作线程. 
CountDownLatch可以保证工作线程的任务执行完毕,主线程再对工作线程进行回收

1. 原理
CountDownLatch,本质上来说,是一个thread safe的计数器,用于主线程和工作线程的同步. 
我所知道的用法有两种:

第一种:在初始化时,需要指定主线程需要等待的任务的个数(count),当工作线程完成 Task Callback后对计数器减1,而主线程通过wait()调用阻塞等待技术器减到0为止.

第二种:初始化计数器值为1,在程序结尾将创建一个线程执行countDown操作并wait()当程序执行到最后会阻塞直到计数器减为0,这可以保证线程池中的线程都start了线程池对象才完成析够,这是一个坑,我在实现ThreadPool的过程中遇到过

2. 实现
CountDownLatch是一个Thread Safe的Couter,它支持的方法主要是两个countDown()和wait() 
countDown就是对counter原子的执行减1操作 
wait就使用条件变量等待counter减到0然后notify.

3.代码
3.1 CountDownLatch.h
 

#ifndef __COUNTDOWNLATCH_H__
#define __COUNTDOWNLATCH_H__
#include "MutexLock.h"
#include "Condition.h"
class CountDownLatch : cl::NonCopy
{
public:
    explicit CountDownLatch(int count)
        : count_(count)
        , mutex_()
        , condition_(mutex_)
    {
    }

    void wait()
    {
        LockGuard<Mutex> lock(mutex_);
        while(count_ > 0)
        {
            condition_.wait();
        }
    }

    void countDown()
    {
        LockGuard<Mutex> lock(mutex_);
        --count_;
        if(count_ == 0)
        {
            condition_.notify_all();
        }
    }

    int getCount() const
    {
        LockGuard<Mutex> lock(mutex_);
        return count_;
    }

private:
    int              count_;
    mutable Mutex    mutex_;
    Condition        condition_;
};

#endif
————————————————
版权声明:本文为CSDN博主「NearXDU」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhangxiao93/article/details/72677207

使用相类似回环栅栏处理

explicit CyclicBarrier(int parties, CyclicBarrier::CyclicBarrierCallBack cb = NULL)
        : parties_(parties)
        , count_(parties)
        , mutex_()
        , condition_(mutex_)
        , cb_(cb)
    {
    }

    void reset()
    {
        LockGuard<Mutex> lock(mutex_);
        nextGeneration();
    }
    
    int wait()
    {
        return dowait(false, 0);
    }
    
    /// Returns the number of parties required to trip this barrier.
    int getParties() const
    {
        return parties_;
    }
    
    /// Returns the number of parties currently waiting at the barrier.
    /// This method is primarily useful for debugging and assertions.
    int getNumberWaiting()
    {
        LockGuard<Mutex> lock(mutex_);
        return parties_ - count_;
    }
    
private:  
    void nextGeneration()
    {
        // signal completion of last generation
        condition_.notify_all();
        // set up next generation
        count_ = parties_;
    }
    
    int dowait(bool timed, int millisecond)
    {
        LockGuard<Mutex> lock(mutex_);
        int index = --count_;
        if (index == 0) // tripped
        {
            if(cb_)
            {
                cb_();
            }
            nextGeneration();
            return 0;         
        }
        
        // loop until tripped, broken, interrupted, or timed out
        for (;;)
        {
            if (!timed)
                condition_.wait();
            else if (millisecond > 0)
                condition_.timed_wait(millisecond);
                
            return index;
        }
    } 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值