voidTaskSystemParallelSpawn::run(IRunnable *runnable, int num_total_tasks) { std::shared_ptr<std::mutex> mu = std::make_shared<std::mutex>(); int count = 0;
auto func = [&count, mu, num_total_tasks, runnable]() { while (true) { // 取出共享变量 mu->lock(); int tmp = count++; mu->unlock();
if (tmp >= num_total_tasks) break; runnable->runTask(tmp, num_total_tasks); } };
std::vector<std::thread> threadId(num_threads); // 子线程 for (int i = 1; i < num_threads; ++i) threadId[i] = std::thread(func);
// 主线程 func();
// 等待子线程 for (int i = 1; i < num_threads; ++i) threadId[i].join(); }
任务 2
任务的状态表示
正常线程池使用任务队列, 这里可以直接记录 runnable
任务有三种状态: 已完成, 完成中, 未完成
已完成: 0 ~ num_finished
完成中: num_finished ~ num_toBeDone - 1
未完成: num_toBeDone ~ num_total_tasks
这里使用了两个锁分别锁住 num_finished 和 num_toBeDone
目的是为了提高性能, 只用一把锁可以保证正确, 但是性能不够
num_total_tasks 不用专门锁的原因是他只会在主线程被写入一次
还需要一个 killed 表示任务是否已经全部执行完毕
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classTaskSystemParallelThreadPoolSpinning: public ITaskSystem { private: int num_threads; std::vector<threadPtr> threads;
IRunnable* runnable;
int num_total_tasks; int num_finished; int num_toBeDone; bool killed;