C++ 多线程 线程池的实现

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<vector>
#include<queue>
#include<memory>
using namespace std;

class comsumer;


//3个接口,解决相互调用和扩展性的问题
class task_ifc {
public:
	virtual void do_work() = 0;
};
class consumer_ifc {
	thread th;
	task_ifc* m_task;
};

int main_();
class consumerManager_ifc {
protected:
	vector<consumer_ifc*> cmer;
	queue<std::unique_ptr<task_ifc>> tasks;
	condition_variable cond;//控制整个流程的环境
	condition_variable cond_task_send_out;//控制任务发送的环境
	mutex inner;//mtx是锁消费者的,inner是锁manage的
	mutex task_sent_out;//这个是的锁
	std::thread th_task_sent_out;
	bool is_working = 1;
	unsigned int max_consumer;//消费者的数量
	unsigned int can_invoke_consumer_size;//当前可调用消费者的个数
	friend class consumer;
	void cmer_over_task() {
		std::lock_guard<std::mutex> lock_g(inner);
		can_invoke_consumer_size++;
	}
	void task_send_out() {//开启子线程,在后台进行任务分配
		std::unique_lock<std::mutex> lock_u(task_sent_out);
		while (is_working) {
			cond_task_send_out.wait(lock_u);
			while (tasks.size() > 0) {//探测到有任务
				if (can_invoke_consumer_size > 0) {//如果有可调用的consumer的话就将分配任务
					cond.notify_all();
				}
				else {
					break;
				}
			}
		}
	}
	void cmer_start_task() {
		std::lock_guard<std::mutex> lock_g(inner);
		can_invoke_consumer_size--;
	}
	friend int main_();
public:
	virtual void push(task_ifc* new_task) = 0;
};




class task :public task_ifc {
	int a = 0;
public:
	task(){}
	void set(int x) {
		a = x;
	}
	void do_work() override {
		cout << ".";
		this_thread::sleep_for(std::chrono::milliseconds(10));
	}
};

class consumer:public consumer_ifc {
	thread th;
	std::unique_ptr<task_ifc> m_task;
	bool is_can_invoke = 1;
	bool is_working = 0;
	consumerManager_ifc* manger;//获取管理者的引用
	std::mutex mtx;
	void task_delete() {
		m_task = nullptr;//将智能指针置空
	}
	consumer(consumerManager_ifc* manger)
		: manger(manger) {
		th = thread(&consumer::take, this);
	}
	consumer(const consumer& cmer) = delete;//删除拷贝构造函数
	consumer(consumer&& cmer) {//支持移动构造函数
		th = std::move(cmer.th);
		m_task = std::move(cmer.m_task);
		is_can_invoke = cmer.is_can_invoke;
		is_working = cmer.is_working;
		manger = cmer.manger;
	}
	void take() {
		unique_lock<std::mutex> lock_u(mtx);
		cout << "线程构造完毕" << endl;
		while (is_can_invoke) {
			manger->cond.wait(lock_u);//等待管理者wake,唤醒后锁会自动lock,保证下面操作的准确性
			if (!get_task()) {//获取任务失败
				continue;
			}
			is_working = true;//设置工作状态
			manger->cmer_start_task();//将开始工作的信息传递给manger
			m_task.get()->do_work();//开始工作
			task_delete();//将完成的任务删除
			manger->cmer_over_task();//将工作完成的信息传递给manger
			is_working = false;//设置工作状态
			manger->cond_task_send_out.notify_one();//提醒manger发配任务
		}
	}
	bool get_task() {
		manger->inner.lock();
		if (manger->tasks.size() == 0) {
			manger->inner.unlock();
			return false;
		}
		m_task =std::move(manger->tasks.front());//获取任务
		manger->tasks.pop();//删除任务
		manger->inner.unlock();
		return true;
	}
	~consumer() {//线程的生命周期是消费者创建开始到消费者析构
		if (th.joinable())
			th.join();
	}
	friend class consumerManager;
};


class consumerManager:public consumerManager_ifc {
public:
	consumerManager(unsigned int size = 1) {//创建一个多线程执行任务的Manger
		cmer.resize(size);
		for (int i = 0; i < size; i++) {
			cmer[i] = new consumer(this);
		}
		can_invoke_consumer_size = size;
		th_task_sent_out = std::thread(&consumerManager::task_send_out, this);
	}
	void push(task_ifc* new_task) {
		std::unique_lock<std::mutex> lock_g(inner);//用inner锁来保证tasks的访问正确性
		std::unique_ptr<task_ifc> unique_new_task(new_task);
		tasks.push(std::move(unique_new_task));
		if (can_invoke_consumer_size > 0) {//获取外界的一个任务,判断是否有消费者可以调用;
			cond.notify_one();
		}
	}
	~consumerManager() {
	}
};
class producer {
	consumerManager_ifc* manger;
public:
	producer(consumerManager_ifc* manger)
		:manger(manger) {}
	void product_task() {
		int x = rand() % 10;
		task* new_task = new task();
		new_task->set(x);
		manger->push(new_task);
	}
	friend int main_();
};

int main_() {
	consumerManager_ifc* manger = new consumerManager(50);
	producer pder(manger);
	while (1) {
		int x; cin >> x;
		if (x == -1) {
			cout << manger->tasks.size() << endl;
		}
		for (int i = 0; i < x; i++) {
			pder.product_task();
		}
		cout << endl << "push_over" << endl;
	}
}

int main() {
	cout << "多线程任务分配器" << endl;
	main_();
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值