c++可以携带任意参数的线程池

本来知乎上有位大神,提供了非常完美的代码。奈何不能传递参数,一开始也不怎么能看懂,更不知道怎么使用。在原有基础上,只是实现了一个可以添加任意参数。

全部代码

#ifndef  THREADPOOL_H
#define  THREADPOOL_H
#include <mutex>
#include <condition_variable>
#include <functional>
#include <queue>
#include <thread>

template <class F>
class BindArgsMover {
public:
	explicit BindArgsMover(F&& f) : f_(std::forward<F>(f)) {}

	template <class...Args>
	auto operator()(Args&&... args)
	{
		f_(std::move(args)...);
	}
private:
	F f_;
};

template <class F, class... Args>
auto bind_simple(F&& f, Args&&...args)
{
	return std::bind(BindArgsMover<F>(std::forward<F>(f)), std::forward<Args>(args)...);
}

class ThreadPool
{
public:
	ThreadPool() = default;
	ThreadPool(ThreadPool&&) = default;
	~ThreadPool() {
		if ((bool)data_) {
			{
				std::lock_guard<std::mutex> lk(data_->mtx_);
				data_->is_shutdown_ = true;
			}

			data_->cond_.notify_all();
		}
	}
	explicit ThreadPool(size_t thread_count) : data_(std::make_shared<data>()) {
		for (size_t i = 0; i < thread_count; ++i) {
			std::thread([data = data_] {
				std::unique_lock<std::mutex> lk(data->mtx_);
				for (;;) { // 获取任务互斥,执行任务并发。
					if (!data->tasks_.empty()) {
						auto current = std::move(data->tasks_.front());
						data->tasks_.pop();
						lk.unlock();
						current();
						lk.lock();
					}
					else if (data->is_shutdown_) {
						break;
					}
					else {
						data->cond_.wait(lk);
					}
				}
				}).detach();// 线程分离,资源由系统回收。
		}
	}

	template<class F, class... Args>
	void execute(F&& f, Args&&... args) {
	   //  解决知乎答主提出的第五点小问题。
		auto task = bind_simple(f, args...);
		{
			std::lock_guard<std::mutex> lk(data_->mtx_);
			data_->tasks_.emplace(task);
		}
		data_->cond_.notify_one();
	}
	bool empty() { return data_->tasks_.empty(); }

private:
	struct data {
		std::mutex mtx_;
		std::condition_variable cond_;
		bool is_shutdown_ = false;
		std::queue<std::function<void()>> tasks_;
	};

	std::shared_ptr<data> data_;
};

使用及测试

#include <iostream>
#include "ThreadPool.h"
class A {
public:
   // 必须是静态方法
	static void test_network(std::string url)
	{
		//访问网络或其他耗时操作。
	}
};
int main() {
 ThreadPool pool{ 10 };
  A a;
	clock_t starts = clock();
	for (int i = 0; i < 50; i++) {
		pool.execute(a.test_network, "116a706dca1443da83b2ef9ed8ffe3b6");// 开启线程池
		//a.test_network("116a706dca1443da83b2ef9ed8ffe3b6")
	}
	while (!pool.empty()){
	//等待所有任务执行完成,实现并不完美,并不是真正的执行完成。
    }
	clock_t ends = clock();
	double time = (double)(ends - starts);
	std::cout << "The test run time:" << time << '\n';
	return 0;
}

通过对比运行结果。开启线程池能够明显节省时间。
参考:知乎回答
最后:都看到这里了,觉得有帮助,可以给github点个星。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值