当前位置: 首页 > 知识库问答 >
问题:

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

夹谷岳
2023-03-14

我有一个带有虚拟方法的类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 Task::Execute(){//do stuff//finished

for(int i = 0; i < children.size(); i++)
{
    children[i]->dependency--;
}

}

所以基本上,只有依赖于0U的任务才能自由执行,所以任务需要等待所有父级完成才能执行。现在的问题是,这个系统变得非常混乱,例如:

    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"
        }
    }

我必须基本上称之为不间断,直到所有的孩子都离开向量。第一次迭代可能只向多线程队列发送2个任务,第二次迭代可能再发送3个,第三次迭代可能再发送7个,等等。这是完全不可预测的,涉及很多分支和循环。也许关于依赖整数的整个想法都不好?

共有2个答案

师赤岩
2023-03-14

可以基于要执行的原始任务构建依赖关系树。假设您想要执行TaskA,这取决于TaskB和TaskC。TaskC本身依赖于TaskD。

让您的任务保存他们的孩子,这是他们的依赖!

class Task : public ITask
{
    public:
     void Execute();

     vector<Task*> children;
};

对于TaskA,向量子项将由TaskB和TaskC组成。TaskB没有其他子任务。TaskC让孩子承担任务。

ThreadingSystem中的线程将解析任务树(从TaskA开始)并搜索叶子,即没有子任务的任务。如果一个线程找到一个叶子,它将确保没有其他线程可以同时运行该任务。一面旗帜可能有用。

执行后,将从树中删除该叶子,并搜索另一片叶子。

如果当前没有可用的叶,线程必须等待一个叶可用。只要一片叶子被处决,你就可以叫醒他们。

ThreadingSystem在没有剩余任务时执行,即TaskA从树中移除时执行。你可以发送一个事件,或者取消对呼叫者的阻止,或者其他什么。

正如你评论一个答案,你这样做是为了教育目的。尝试实现一个树,如果你完成了,你可以尝试实现一个(定向)图。或执行周期检测。尝试加快查找/缓存树叶等的性能。

或使用现有的框架

华良才
2023-03-14
  • 使用getter/setter,而不是直接访问依赖项
    • 比如child-

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

 类似资料:
  • Celery 是一个 Python 的任务队列,包含线程/进程池。曾经有一个 Flask 的集成, 但在 Celery 3 重构了内部细节后变得不必要了。本指导补充了如何妥善在 Flask 中使用 Celery 的空白,但假设你已经读过了 Celery 官方文档中的教程 使用 Celery 的首要步骤 安装 Celery Celery 提交到了 Python Package Index (PyPI

  • 作为考试准备的一部分,我一直在努力解决问题,我想我需要你的帮助。我需要写一个布尔方法,需要整数数组(正和负),并返回true,如果数组可以被拆分为两个相等的组,每个组的数字的量等于另一组。对于示例,对于这个数组: 该方法将返回true,因为-3514=12-913。 对于此阵列: 该方法将返回false,因为即使-3 5 14 -12 = -9 13,等式每边的数字量也不相等。 对于阵列: 该方法

  • 任务是要安排的基本单位。 基础 任务因其而异taskid。(默认值:md5(url),可以通过覆盖def get_taskid(self, task)方法更改) 任务在不同项目之间隔离。 任务有4个状态: 活性 失败 成功 坏 - 没用过 仅安排处于活动状态的任务。 任务按顺序提供priority。 时间表 新任务 当一项新任务(从未见过)进来时: 如果exetime已设置但未到达,则将其置于基于

  • 我想为一个Android项目创建一个自定义的gradle任务,这将调用其他任务链,取决于构建风格和构建配置。 所以,这就是我在build.gradle.kts中所做的事情(我们使用kotlin脚本) 所以如果我运行./gradlew任务 null

  • 问题内容: 我的问题与这里的这个问题密切相关。如此处所述,我希望主线程等待,直到工作队列为空并且所有任务都已完成。但是,我的情况是每个任务都可能递归地导致新任务被提交进行处理。这使得收集所有这些任务的未来变得有点尴尬。 我们当前的解决方案使用忙等待循环来等待终止: numTasks是随着创建每个新任务而增加的值。这可以工作,但是由于繁忙的等待,我认为它不是很好。我想知道是否有一个好方法可以使主线程