C++ (Qt)if (std::atomic_fetch_sub(&MyTask::taskCount, 1) == 1) MyTask::mPromise.set_value(1);
C++ (Qt)std::atomic_int test(5);if (--test <= 0) ....;
ASM lock sub QWORD PTR taskCount[rip], 1 je .L13 ret
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(); m_promise = std::promise<void>(); for (const auto & task : task_group) m_queue.push(task); } m_loop_cv.notify_one(); }
C++ (Qt)threap_pool pool; pool.add_tasks_group(tasks_group); ... pool.add_tasks_group(tasks_group); pool.wait_for_done();
C++ (Qt) void join() { m_is_stop = true; m_loop_cv.notify_all(); for (auto & th : m_threads) { if (th.joinable()) th.join(); } }
C++ (Qt)#include <taskflow/taskflow.hpp> // Cpp-Taskflow is header-only int main(){ tf::Executor executor; tf::Taskflow taskflow; auto [A, B, C, D] = taskflow.emplace( [] () { std::cout << "TaskA\n"; }, // task dependency graph [] () { std::cout << "TaskB\n"; }, // [] () { std::cout << "TaskC\n"; }, // +---+ [] () { std::cout << "TaskD\n"; } // +---->| B |-----+ ); // | +---+ | // +---+ +-v-+ A.precede(B); // A runs before B // | A | | D | A.precede(C); // A runs before C // +---+ +-^-+ B.precede(D); // B runs before D // | +---+ | C.precede(D); // C runs before D // +---->| C |-----+ // +---+ executor.run(taskflow).wait(); return 0;}
C++ (Qt)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(); } }
C++ (Qt)void worker() { for(;;) { std::unique_lock<std::mutex> lock(m_mutex); m_loop_cv.wait(lock, [&]() { return !m_queue.empty() || m_is_stop; }); if (m_is_stop && m_queue.empty()) return; std::function<void()> work_function(m_queue.front()); m_queue.pop(); lock.unlock(); work_function(); } }