c++多线程设计模式之一(Latch门阀模式)

使用场景: 多个任务同时完成,才能进入下一步时使用;

  • 例如:同学们都到齐了,老师才开始上课;
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <random>
#include <chrono>

static std::default_random_engine e(time(0)); 
static std::uniform_int_distribution<unsigned> u(0, 9); //随机数分布对象

class Latch {
	public:
		Latch(int limit) {
			this->limit_ = limit;	
		}
	
		virtual void await() = 0;
		virtual void count_down() = 0; 
		virtual int get_unarrived() = 0;
	protected:
		int limit_;
};

class CountDownLatch : public Latch {
	public:
		using Latch::Latch;
	
	void await() override {
		std::unique_lock<std::mutex> lk(mtx_);
		cv_.wait(lk, [&]{
			//std::cout << "limit_: " << limit_ << std::endl;
			return (limit_ == 0);
			});
	}		
		
	void count_down() override {
		std::unique_lock<std::mutex> lk(mtx_);
		limit_--;
		cv_.notify_all();
	}

	int get_unarrived() override {
		std::unique_lock<std::mutex> lk(mtx_);
		return limit_;		
	}

	private:
		std::mutex mtx_;
		std::condition_variable cv_;
};

class ProgrammerTravel {
    public:
	ProgrammerTravel(Latch* latch, std::string name, std::string vehicle){
		latch_ = latch;
		vehicle_ = vehicle;
		name_ = name;
	}
	~ProgrammerTravel(){
		thd_.join();
	}

	void run() {
		thd_ = std::thread([&]{
			int sec = u(e);
			std::cout<< name_ << " take " << vehicle_ << ", need time: " << sec << "."<< std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(sec));
			std::cout << name_ << " arrived." << std::endl;
			latch_->count_down();
		});		

	}

	private:
	Latch* latch_;
	std::string vehicle_;
	std::string name_;
	std::thread thd_;
};

int main(int argc, char** argv) {
	Latch* latch = new CountDownLatch(4);
	ProgrammerTravel li(latch, "Li", "Bus");
	ProgrammerTravel liu(latch, "Liu", "bike");
	ProgrammerTravel lv(latch, "Lv", "subway");
	ProgrammerTravel zhang(latch, "Zhang", "walk");

	li.run();
	liu.run();
	lv.run();
	zhang.run();

	latch->await();
	std::cout << "all persons arrived finally." << std::endl;
	delete latch;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值