From 01e4aafa2c8e28542d88641977d5022fdef17756 Mon Sep 17 00:00:00 2001 From: NITEACE <135036433+NITEACE@users.noreply.github.com> Date: Sat, 20 Jul 2024 20:30:43 +0800 Subject: [PATCH] Update ThreadPool.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.使用std::invoke_result替代std::result_of std::result_of已被C++17中的std::invoke_result取代,前者在C++20中被弃用。为了保证代码的现代性和兼容性,使用了std::invoke_result。 2.捕获和处理任务中的异常 当前实现中,如果任务抛出异常,可能导致线程终止。所以我尝试在任务执行时捕获异常,并提供相应的处理机制。 3.增加线程池状态查询功能 增加了一些方法,可以查询线程池的状态,例如:当前活跃线程数、任务队列长度等,便于调试和监控。 --- ThreadPool.h | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/ThreadPool.h b/ThreadPool.h index 4183203..3f20b08 100644 --- a/ThreadPool.h +++ b/ThreadPool.h @@ -10,31 +10,37 @@ #include #include #include +#include class ThreadPool { public: ThreadPool(size_t); template auto enqueue(F&& f, Args&&... args) - -> std::future::type>; + -> std::future::type>; ~ThreadPool(); + + // 获取当前任务队列大小 + size_t getTaskCount(); + // 获取当前活跃线程数 + size_t getActiveThreadCount(); + private: - // need to keep track of threads so we can join them - std::vector< std::thread > workers; - // the task queue - std::queue< std::function > tasks; + // 跟踪线程以便我们可以加入它们 + std::vector workers; + // 任务队列 + std::queue> tasks; - // synchronization + // 同步 std::mutex queue_mutex; std::condition_variable condition; bool stop; }; - -// the constructor just launches some amount of workers + inline ThreadPool::ThreadPool(size_t threads) - : stop(false) + : stop(false) { - for(size_t i = 0;itasks.pop(); } - task(); + try { + task(); + } catch (const std::exception& e) { + // 处理任务中的异常 + } } } ); } -// add new work item to the pool template auto ThreadPool::enqueue(F&& f, Args&&... args) - -> std::future::type> + -> std::future::type> { - using return_type = typename std::result_of::type; + using return_type = typename std::invoke_result::type; - auto task = std::make_shared< std::packaged_task >( + auto task = std::make_shared>( std::bind(std::forward(f), std::forward(args)...) ); @@ -73,7 +82,6 @@ auto ThreadPool::enqueue(F&& f, Args&&... args) { std::unique_lock lock(queue_mutex); - // don't allow enqueueing after stopping the pool if(stop) throw std::runtime_error("enqueue on stopped ThreadPool"); @@ -83,7 +91,6 @@ auto ThreadPool::enqueue(F&& f, Args&&... args) return res; } -// the destructor joins all threads inline ThreadPool::~ThreadPool() { { @@ -95,4 +102,14 @@ inline ThreadPool::~ThreadPool() worker.join(); } +size_t ThreadPool::getTaskCount() { + std::unique_lock lock(queue_mutex); + return tasks.size(); +} + +size_t ThreadPool::getActiveThreadCount() { + std::unique_lock lock(queue_mutex); + return workers.size(); +} + #endif