From dd51e639a46861fdb9ae87788fb9d17af94dcaac Mon Sep 17 00:00:00 2001 From: gitrepocz <1987746397@qq.com> Date: Sat, 31 May 2025 20:39:38 +0800 Subject: [PATCH] =?UTF-8?q?2025=200531=20=E5=85=B3=E4=BA=8E=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E6=B1=A0=E7=9A=84=E7=AC=94=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../async_function/async_function/thread_pool.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/concurrent/day07-async_function/async_function/async_function/thread_pool.h b/concurrent/day07-async_function/async_function/async_function/thread_pool.h index bf127bb..5e1dcf0 100644 --- a/concurrent/day07-async_function/async_function/async_function/thread_pool.h +++ b/concurrent/day07-async_function/async_function/async_function/thread_pool.h @@ -9,12 +9,12 @@ #include #include #include - +// 线程池不可以用来处理强相关的任务和需要顺序执行的任务 class ThreadPool { public: ThreadPool(const ThreadPool&) = delete; ThreadPool& operator=(const ThreadPool&) = delete; - + // 线程池需要是单例模式 static ThreadPool& instance() { static ThreadPool ins; return ins; @@ -33,6 +33,7 @@ public: start(); } ~ThreadPool() { + // 线程池析构时需要把所有的线程都停止 stop(); } @@ -41,12 +42,19 @@ public: using RetType = decltype(f(args...)); if (stop_.load()) return std::future{}; + // std::bind可以把函数指针和参数进行绑定 并返回一个不需要输入参数的可调用对象 + // 所以此处使用bind之后无需 在构建task时不用再函数中输入参数 auto task = std::make_shared>( std::bind(std::forward(f), std::forward(args)...)); std::future ret = task->get_future(); { + // 入队存任务 出队执行任务 std::lock_guard cv_mt(cv_mt_); + // 此处也是一个细节 注意using Task = std::packaged_task; + // 这里的void写死了 如果直接传task进去就只能用于返回值为空的func + // 写成[task] { (*task)(); } 则是将package_task放入一个返回值为空的lambda表达式中 这样就不用再管func返回值了 + // package重载了() 运算符 是一个可调用对象 tasks_.emplace([task] { (*task)(); }); } cv_lock_.notify_one(); @@ -64,6 +72,10 @@ private: while (!this->stop_.load()) { Task task; { + // stop为线程池停止标志 在设置为true时 通知所有的工作线程应该退出 + // 确保所有已入队的任务完成后再停止线程池 + // 防止新任务加入时线程池已经停止 + // 唤醒等待在条件变量上的线程 std::unique_lock cv_mt(cv_mt_); this->cv_lock_.wait(cv_mt, [this] { return this->stop_.load() || !this->tasks_.empty(); -- Gitee