基于C++11的threadpool线程池(简洁且可以带任意多的参数)
介绍
线程池是一种并发编程中提高性能与效率的技术,可以避免频繁创建和销毁线程,提升程序运行效率。本文将介绍基于C++11的线程池实现,并且可以传递任意多的参数。
实现
线程池主要由任务队列和线程池管理器两个部分组成。线程池管理器主要用来创建、销毁线程和管理任务队列,线程池中的任务队列存储着需要执行的任务。下面是线程池的详细实现过程:
- 首先需要定义一个任务队列:
std::queue<std::function<void()>> task_queue;
std::mutex task_mutex;
std::condition_variable task_cv;
int running_threads = 0;
- 定义一个添加任务的函数:
template<typename F, typename... Args>
void add_task(F&& f, Args&&... args)
{
auto task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
std::unique_lock<std::mutex> lock(task_mutex);
task_queue.push(std::move(task));
task_cv.notify_one();
}
- 定义一个线程池管理器,用于创建、销毁线程和管理任务队列:
class ThreadPool
{
private:
std::vector<std::thread> threads;
int num_threads;
bool stop;
public:
ThreadPool(int num_threads) : num_threads(num_threads), stop(false)
{
for (int i = 0; i < num_threads; i++)
{
threads.emplace_back([this]()
{
while (true)
{
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(task_mutex);
task_cv.wait(lock, [this]()
{
return stop || !task_queue.empty();
});
if (stop && task_queue.empty())
{
break;
}
task = std::move(task_queue.front());
task_queue.pop();
}
running_threads++;
task();
running_threads--;
task_cv.notify_all();
}
});
}
}
~ThreadPool()
{
{
std::unique_lock<std::mutex> lock(task_mutex);
stop = true;
}
task_cv.notify_all();
for (auto& thread : threads)
{
thread.join();
}
}
};
- 最后可以用下面的方式添加任务到线程池:
ThreadPool thread_pool(4);
// 添加一个不带参数的任务
thread_pool.add_task([]() {
std::cout << "Task 1" << std::endl;
});
// 添加带参数的任务
int a = 1;
std::string b = "abc";
thread_pool.add_task([a, b]() {
std::cout << "Task 2" << std::endl;
std::cout << "a: " << a << std::endl;
std::cout << "b: " << b << std::endl;
});
示例
示例一
#include <iostream>
#include "threadpool.h"
void print(int num)
{
for (int i = 0; i < num; i++)
{
std::cout << "Thread " << std::this_thread::get_id() << ": " << i << std::endl;
}
}
int main()
{
ThreadPool thread_pool(4);
for (int i = 0; i < 4; i++)
{
thread_pool.add_task(print, 10);
}
return 0;
}
上述代码中,首先创建一个线程池,然后向线程池中添加4个打印任务,每个任务打印10条信息。运行结果如下:
Thread 140599199620864: 0
Thread 140599207013568: 0
Thread 140599199620864: 1
Thread 140599200729344: 0
Thread 140599199620864: 2
Thread 140599207013568: 1
Thread 140599199620864: 3
Thread 140599207013568: 2
Thread 140599199620864: 4
Thread 140599200729344: 1
Thread 140599207013568: 3
Thread 140599199620864: 5
Thread 140599200729344: 2
Thread 140599207013568: 4
Thread 140599200729344: 3
Thread 140599199620864: 6
Thread 140599207013568: 5
Thread 140599199620864: 7
Thread 140599200729344: 4
Thread 140599199620864: 8
Thread 140599207013568: 6
Thread 140599199620864: 9
Thread 140599200729344: 5
Thread 140599207013568: 7
Thread 140599200729344: 6
Thread 140599207013568: 8
Thread 140599200729344: 7
Thread 140599207013568: 9
Thread 140599200729344: 8
Thread 140599200729344: 9
示例二
#include <iostream>
#include "threadpool.h"
int add(int a, int b)
{
std::cout << "Thread " << std::this_thread::get_id() << ": " << a << "+" << b << "=" << a + b << std::endl;
return a + b;
}
std::string concat(std::string a, std::string b)
{
std::cout << "Thread " << std::this_thread::get_id() << ": " << a << "+" << b << "=" << a + b << std::endl;
return a + b;
}
int main()
{
ThreadPool thread_pool(4);
int result1 = thread_pool.add_task(add, 1, 2).get();
std::string result2 = thread_pool.add_task(concat, "hello", "world").get();
std::cout << "Result1: " << result1 << std::endl;
std::cout << "Result2: " << result2 << std::endl;
return 0;
}
上述代码中,首先创建一个线程池,然后向线程池中添加两个任务,分别是计算两个整数的和和拼接两个字符串。最后获取任务的执行结果,并打印出来。运行结果如下:
Thread 140732506105856: 1+2=3
Thread 140732505235200: hello+world=helloworld
Result1: 3
Result2: helloworld
总结
本文介绍了基于C++11的线程池的实现方式,并且可以传递任意多的参数。线程池的实现主要包括任务队列和线程池管理器两个部分。最后给出了两个使用线程池的示例。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于C++11的threadpool线程池(简洁且可以带任意多的参数) - Python技术站