定义了一个 ThreadPool 类,在每个线程中不断地从任务队列中获取任务并执行,直到线程池被停止。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <queue>
class ThreadPool {
public:
ThreadPool(int numThreads) : stop(false) {
std::cout << "----4------" << std::endl;
for (int i = 0; i < numThreads; ++i) {
threads.emplace_back([this] {
while (true) {
std::unique_lock<std::mutex> lock(mutex);
condition.wait(lock, [this] { return stop || !tasks.empty(); });//终止或者不为空就不用阻塞了
if (stop && tasks.empty()) {
return;
}
std::function<void()> task(std::move(tasks.front()));//取任务
tasks.pop();
lock.unlock();//取到任务了,让其他的线程去取任务
task();//执行任务
}
});
}
}
~ThreadPool() {
std::cout << "----3------" << std::endl;
{
std::unique_lock<std::mutex> lock(mutex);
stop = true;//线程池创建结束
}
condition.notify_all();//通知所有线程stop为true,通知线程要把队列中所有任务完成
for (std::thread& thread : threads) {
thread.join();
}
}
template<typename F, typename... Args> //传的函数参数个数不确定
void enqueue(F&& f, Args&&... args) {//函数模板的右值引用就是万能引用
std::function<void()> task(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
{//注意锁的作用域范围
std::unique_lock<std::mutex> lock(mutex);
tasks.emplace(std::move(task));
//lock.unlock();
}//超出作用域自动解锁
condition.notify_one();
}
private:
std::vector<std::thread> threads;//线程数组,多个线程,线程从任务队列中取任务完成
std::queue<std::function<void()>> tasks;//任务队列,需要完成多个任务,任务一般是一个函数,所以使用function去维护
std::mutex mutex;//
std::condition_variable condition;//条件变量
bool stop;//线程什么时候终止
};
void printt(){
std::cout << "----2------" << std::endl;
}
int main() {
ThreadPool pool(4);
for (int i = 0; i < 8; ++i) {
// 将多个任务放进线程池中等待运行
pool.enqueue([i] {
std::cout << "Task " << i << " is running, thread(id): " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Task " << i << " is done" << std::endl;
});
}
return 0;
}