c++可以携带任意参数的线程池
本来知乎上有位大神,提供了非常完美的代码。奈何不能传递参数,一开始也不怎么能看懂,更不知道怎么使用。在原有基础上,只是实现了一个可以添加任意参数。全部代码#ifndefTHREADPOOL_H#defineTHREADPOOL_H#include <mutex>#include <condition_variable>#include <functional>#
·
本来知乎上有位大神,提供了非常完美的代码。奈何不能传递参数,一开始也不怎么能看懂,更不知道怎么使用。在原有基础上,只是实现了一个可以添加任意参数。
全部代码
#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)