Notestd::thread 无拷贝构造函数,无法复制只能引用 &。 Tip<condition_variable> 里包含了 <mutex> 头文件。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869#include <iostream>#include <thread>#include <condition_variable>#include <queue>#include <vector>#include <functional>#include <atomic>class ThreadPool {private: std::mutex mtx; std::condition_variable condition; std::queue<std::function<void()>> tasks; std::atomic<bool> stop; std::vector<std::thread> threads;public: ThreadPool(int num_threads) : stop{ false } { for (int i = 0; i < num_threads; i++) { threads.emplace_back([this]() { while (true) { std::unique_lock<std::mutex> lock(mtx); condition.wait(lock, [this]() { return !tasks.empty() || stop; }); if (stop && tasks.empty()) return; std::function<void()> task(std::move(tasks.front())); tasks.pop(); lock.unlock(); task(); } }); } } ~ThreadPool() { { std::lock_guard<std::mutex> lock(mtx); stop = true; } condition.notify_all(); for (auto& t : threads) { t.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)...); //auto task = [func = std::forward<F>(f), tup = std::make_tuple(std::forward<Args>(args)...)]() mutable { std::apply(std::move(func), std::move(tup)); }; C++17 引入 <tuple> 头文件 std::apply //auto task = [func = std::forward<F>(f), ...args = std::forward<Args>((args)...)]() mutable { func = std::move((args)...); }; C++20 才支持包扩展用于初始化捕获 [...args = ...],用 lambda 替代 std::bind if (stop) throw std::runtime_error("enqueue on stopped ThreadPool"); { std::lock_guard<std::mutex> lock(mtx); tasks.emplace(std::move(task)); //std::cout<< "task loaded" << "\n"; } condition.notify_one(); }};int main() { ThreadPool threadpool(6); for (int i = 0; i < 500; i++) { threadpool.enqueue([i]() { std::cout << "task: " << i << " is running" << "\n"; std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::cout << "task: " << i << " is done" << std::endl; }); } return 0;}