multithreading - 如何避免基于任务的程序的递归任务列表遍历?

标签 multithreading algorithm scheduled-tasks

我有一个带有虚方法的 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->AddDependencychild->SatisfyDependency
  • child->SatisfyDependency 应该在依赖计数为零时将 child 添加到队列中。
  • 现在,将 child 添加到队列不是轮询,而是直接由“不再依赖”事件触发。

不过,如果可以的话,您应该考虑引入一个已经调试好的基于任务的线程池库。

关于multithreading - 如何避免基于任务的程序的递归任务列表遍历?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20410236/

相关文章:

c# - 等待/异步并跳出框框

c# - 信号量:了解初始和最大请求​​数

javascript - 在javascript ES6中寻找更高效的排序算法

algorithm - 这种多处理器线程调度算法是否适用于所有情况?

windows - 从 Powershell 更新计划任务脚本

java - 使用 Java 进行跨平台作业调度

multithreading - 使用互斥锁和条件变量的线程同步

c# - 界面无法更新

sql-server - SQL使用什么算法?

c# - 如何在 Azure 上安排作业?