C++ (Qt)// workervoid MyTask::operator()( void ){ .... if (--MyTask::taskCount <= 0) MyTask::mPromise.set_value(1);} // main threadMyTask::taskCount = tasks.size();MyTask::mPromise = std::promise<int> ();std::future<int> future = MyTask::mPromise.get_future(); for (int i = 0; i < tasks.size(); ++i) pool.submit(tasks[i]); future.wait();}
C++ (Qt)// workervoid MyTask::operator()( void ){ .... if (--MyTask::taskCount <= 0) MyTask::mPromise.set_value(1);}
C++ (Qt)#ifndef THREAD_POOL_H#define THREAD_POOL_H #include <list>#include <queue>#include <thread>#include <mutex>#include <condition_variable>#include <atomic>#include <future>#include <memory>#include <functional> class thread_pool{public: thread_pool(size_t num_threads = std::max(size_t(1), size_t(std::thread::hardware_concurrency()))) : m_is_stop(false), m_counter(0) { for (size_t i = 0; i < num_threads; ++i) m_threads.push_back(std::thread(&thread_pool::worker, this)); } thread_pool(const thread_pool &) = delete; thread_pool(thread_pool &&) = delete; thread_pool & operator=(const thread_pool &) = delete; thread_pool & operator=(thread_pool &&) = delete; void join() { m_is_stop = true; m_loop_cv.notify_all(); for (auto & th : m_threads) { if (th.joinable()) th.join(); } } template<class G> void add_task_group(const G & task_group) { { std::lock_guard<std::mutex> lock(m_mutex); m_counter += task_group.size(); for (const auto & task : task_group) m_queue.push(task); } m_loop_cv.notify_one(); } void wait_for_done() { m_promise.get_future().wait(); } private: std::atomic_bool m_is_stop; std::atomic_int m_counter; std::list<std::thread> m_threads; std::queue<std::function<void()>> m_queue; std::mutex m_mutex; std::condition_variable m_loop_cv; std::promise<void> m_promise; void worker() { while (!m_is_stop) { std::unique_lock<std::mutex> lock(m_mutex); m_loop_cv.wait(lock, [&]() { return !m_queue.empty() || m_is_stop; }); if (m_is_stop) return; std::function<void()> work_function(m_queue.front()); m_queue.pop(); lock.unlock(); work_function(); if (!--m_counter) m_promise.set_value(); } }}; #endif // THREAD_POOL_H
C++ (Qt)thread_pool pool; const size_t num_tasks = 100; std::vector<std::function<void()>> tasks; for (size_t i = 0; i < num_tasks; ++i) tasks.push_back(task); pool.add_task_group(tasks); pool.wait_for_done(); pool.join();
C++ (Qt) template<class G> void add_task_group(const G & task_group) { { std::lock_guard<std::mutex> lock(m_mutex); m_counter += task_group.size(); for (const auto & task : task_group) m_queue.push(task); } m_loop_cv.notify_one(); }
C++ (Qt) void join() { m_is_stop = true; m_loop_cv.notify_all(); for (auto & th : m_threads) { if (th.joinable()) th.join(); } }