ThreadPool 代码介绍
该代码实现了一个简单的 C++ 线程池(ThreadPool),用于管理并发执行的任务。
头文件
#include <queue>
#include <mutex>
#include <future>
#include <iostream>
#include <condition_variable>
using namespace std;
std::mutex mtx;
class ThreadPool {
public:
ThreadPool(int thread_num = THREAD_MAX);
template <typename function, typename... args>
void addtask(function&& fnc, args&&... arg);
~ThreadPool();
private:
bool stop;
std::vector<std::thread> threads;
std::queue<std::function<void()>> tasks;
std::mutex queuemutex;
std::condition_variable condition;
};
void task(int id);
构造函数
构造函数 ThreadPool::ThreadPool(int thread_num)
接收一个可选的线程数参数 thread_num
,默认为 THREAD_MAX
。在构造函数中,根据指定的线程数创建线程,并使用 lambda 表达式作为线程函数。每个线程会持续运行一个循环,等待任务队列中有可执行的任务,然后取出任务并执行。
ThreadPool::ThreadPool(int thread_num):stop(false)
{
for (int i = 0; i < thread_num; i++)
{
threads.emplace_back([this] {while (true)
{
std::function<void()> task;
std::unique_lock<std::mutex> lock(queuemutex);
condition.wait(lock, [this] {return stop || !tasks.empty(); });
if (stop && tasks.empty())
{
return;
}
task = std::move(tasks.front());
tasks.pop();
lock.unlock();
task();
}});
}
}
添加任务
成员函数 ThreadPool::addtask
用于向线程池添加任务。它接收一个可调用对象 fnc
和可变参数 args...
,通过使用 std::bind
和 std::forward
进行参数绑定和转发,创建一个 std::packaged_task
对象,并将其放入任务队列中。添加任务后,通过调用 condition.notify_one()
来通知一个等待中的线程有任务可执行。
void ThreadPool::addtask(function&&fnc, args&&...arg)
{
auto task = std::make_shared<std::packaged_task<void()>>(std::bind(std::forward<function>(fnc), std::forward<args>(arg)...));
std::unique_lock<std::mutex> lock(queuemutex);
tasks.emplace([task]() { (*task)(); });
lock.unlock();
condition.notify_one();
}
析构函数
析构函数 ThreadPool::~ThreadPool()
负责线程池的清理工作。它首先将 stop
标志设置为 true
,然后通过调用 condition.notify_all()
通知所有等待中的线程停止等待。接下来,使用循环等待所有线程执行完成,通过调用 thread.join()
加入主线程。
ThreadPool::~ThreadPool()
{
std::unique_lock<std::mutex> lock(queuemutex);
stop = true;
condition.notify_all();
for (std::thread& thread : threads)
{
thread.join();
}
}
示例任务函数
函数 task
是一个示例任务函数,它接收一个整数参数 id
,并在控制台输出任务的执行信息。
void task(int id) {
std::unique_lock<std::mutex> lock(mtx);
std::cout << "task " << id << " executed by thread " << std::this_thread::get_id() << std::endl;
lock.unlock();
}
主函数
在 main
函数中,首先创建了一个 ThreadPool
对象 threadpool
。然后使用一个循环向线程池添加 10 个任务,每个任务都是调用 task
函数,并传入不同的任务 ID。最后,通过 std::this_thread::sleep_for
函数使主线程休眠 2 秒,以等待所有任务执行完成。
int main() {
/*创建线程池*/
ThreadPool threadpool;
for (int i = 0; i < 10; ++i)
{
threadpool.addtask(task, i);
}
std::this_thread::sleep_for(std::chrono::seconds(2));
return 0;
}
以上是对 ThreadPool 代码的详细介绍,,希望对您有所帮助。