我有一个带有虚方法的 ITask 类:
class ITask
{
public:
virtual void Execute() = 0;
};
我做了一个系统,在不同的线程上分配任务,让它们并行执行。问题是,我需要一些任务在某些其他任务完成之前不能执行。一个任务可以依赖于多个父任务,所以我不能按照这样的方式做一些事情:
void Task::Execute()
{
//do stuff
//finished
for(int i = 0; i < children.size(); i++)
{
ThreadingSystem::QueuedTasks.push_back(children[i]);
}
}
所以我做了这样的事情:
class Task : public ITask
{
public:
void Execute();
unsigned int dependency;
vector<Task*> children;
};
void 任务::执行() { //做东西 //完成
for(int i = 0; i < children.size(); i++)
{
children[i]->dependency--;
}
所以基本上只有依赖 0U 的 Task 可以自由执行,所以一个 Task 需要等待它的所有父任务完成才能执行。现在的问题是,这个系统变得非常困惑,例如:
for(int i = 0; i < children.size(); i++)
{
if(children[i]->dependency == 0U)
{
ThreadingSystem::QueuedTasks.push_back(children[i]);
//either remove added task from children or set a flag in it to mark as "queued"
}
}
我基本上必须不停地调用它,直到所有 child 都离开向量。第一次迭代可能只发送 2 个任务到多线程队列,第二次迭代可能再发送 3 个,第三次迭代再发送 7 个,等等.它完全不可预测,并且涉及很多分支和循环。也许关于依赖整数的整个想法是错误的?
最佳答案
- 使用 getters/setters 而不是直接访问
dependencies
。- 类似于
child->AddDependency
和child->SatisfyDependency
。
- 类似于
child->SatisfyDependency
应该在依赖计数为零时将 child 添加到队列中。- 现在,将 child 添加到队列不是轮询,而是直接由“不再依赖”事件触发。
不过,如果可以的话,您应该考虑引入一个已经调试好的基于任务的线程池库。
关于multithreading - 如何避免基于任务的程序的递归任务列表遍历?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20410236/