民间, 我有个问题。我是在python中编写一个脚本,它包含几个模块。某些模块依赖于其他模块,因此只有在成功运行相关模块后才能运行它们。因此,每个模块都派生自一个基类模块,并覆盖一个名为DEPENDENCIES的列表,该列表是在运行此模块时要满足的依赖列表。有一个模块需要在所有其他模块之前运行。目前我正在做这样的事情。
modules_to_run.append(a)
modules_to_run.append(b)
modules_to_run.append(c)
.....
.....
modules_to_run.append(z)
# Very simplistically just run the Analysis modules sequentially in
# an order that respects their dependencies
foundOne = True
while foundOne and len(modules_to_run) > 0:
foundOne = False
for module in modules_to_run:
if len(module.DEPENDENCIES) == 0:
foundOne = True
print_log("Executing module %s..." % module.__name__, log)
try:
module().execute()
modules_to_run.remove(module)
for module2 in modules_to_run:
try:
module2.DEPENDENCIES.remove(module)
except:
#module may not be in module2's DEPENDENCIES
pass
except Exception as e:
print_log("ERROR: %s did not run to completion" % module.__name__, log)
modules_to_run.remove(module)
print_log(e, log)
for module in modules_to_run:
name = module.__name__
print_log("ERROR: %s has unmet dependencies and could not be run:" % name, log)
print_log(module.DEPENDENCIES, log)
现在我看到一些模块需要很长时间才能执行,而脚本调试时间太长。所以我想让它多线程,以便独立的模块可以同时运行,从而节省时间。所以我想要一个解决方案,在每次迭代之后,我将重新计算'n'个独立模块(其中'n'是线程的最大数量,通常是2开始)并且并行执行它们并等待它们在下一次迭代之前完成。我不太了解算法,所以我被卡住了。请各位大家帮帮我找一个算法,在每次迭代后找到最大的'n'组独立模块,这些算法并不相互依赖。
答案 0 :(得分:2)
我最近发布了topological sorting in a question about make -j
的说明。情缘!来自维基百科的文章:
拓扑排序(拓扑顺序)的规范应用是安排一系列工作或任务;拓扑排序算法最早是在20世纪60年代早期在PERT技术中用于项目管理中的调度(Jarnagin 1960)。作业由顶点表示,如果在作业y开始之前必须完成作业x,则从x到y存在边缘(例如,洗衣服时,洗衣机必须在我们将衣服晾干之前完成)。然后,拓扑排序给出了执行作业的顺序。
粗略轮廓:
阅读这些链接以获取更详细的说明。
答案 1 :(得分:1)
从您的设置说明中,您也可以直接进行此操作。
看起来每个模块都知道它的依赖关系。然后在每个模块中添加一个谓词函数,说明它是否可以运行,这很简单。当且仅当满足所有模块的先决条件依赖关系时,才能运行模块。
顶级模块没有依赖关系,所以它们可以从一开始就运行。
基本上,这是部分拓扑排序的一个简单实现(您不必探索所有依赖图,只需保持最高级别)。
要注意两个陷阱:
如果你的依赖包含循环(A依赖于B取决于C取决于A)它可能永远循环(这意味着问题没有解决方案)。您应检测此案例并报告和错误。
您可以运行的模块可能少于线程数。这应该不是一个错误。然后,当您有可用的模块运行或者询问每个模块是否可以运行时,您已找到解决方案。