Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何并行启动多个计算,同时在第一个计算返回时停止所有计算?[Python]_Python_Parallel Processing_Multiple Processes - Fatal编程技术网

如何并行启动多个计算,同时在第一个计算返回时停止所有计算?[Python]

如何并行启动多个计算,同时在第一个计算返回时停止所有计算?[Python],python,parallel-processing,multiple-processes,Python,Parallel Processing,Multiple Processes,如何并行启动多个计算,同时在第一个计算返回时停止所有计算 我想到的应用程序如下:计算某个值有多种方法;根据功能参数,每种方法需要不同的时间;通过并行启动计算,每次将自动“选择”最快的计算,并停止其他计算 现在,有一些“细节””使得这个问题更加困难: 要计算的函数参数包括函数(从数据点计算;它们不是顶级模块函数)。实际上,计算是两个函数的卷积。我不确定如何将这样的函数参数传递给子流程(它们不可拾取) 我无法访问所有的计算代码:有些计算是由Scipy内部完成的(可能通过Fortran或C代码)。我

如何并行启动多个计算,同时在第一个计算返回时停止所有计算

我想到的应用程序如下:计算某个值有多种方法;根据功能参数,每种方法需要不同的时间;通过并行启动计算,每次将自动“选择”最快的计算,并停止其他计算

现在,有一些“细节””使得这个问题更加困难:

  • 要计算的函数参数包括函数(从数据点计算;它们不是顶级模块函数)。实际上,计算是两个函数的卷积。我不确定如何将这样的函数参数传递给子流程(它们不可拾取)
  • 我无法访问所有的计算代码:有些计算是由Scipy内部完成的(可能通过Fortran或C代码)。我不确定线程是否提供类似于可以发送到进程的终止信号的东西

这是Python相对容易做到的吗?

由于全局解释器锁,您很难通过这种方式获得任何加速。实际上,即使是Python中的多线程程序也只在一个内核上运行。因此,您只需以1/N倍的速度执行N个进程。即使其中一个完成的时间是其他人的一半,你仍然会在全局中损失时间。

如果你还没有完成,我会看一下模块。它提供了一种将任务卸载到单独流程的方法,同时为您提供了一个简单的界面

它提供了与您在
线程化
模块中获得的相同类型的primative,例如,用于在任务之间传递消息的工作池和队列,但它允许您回避GIL问题,因为您的任务实际上在单独的进程中运行

你想要的东西的实际语义是非常具体的,所以我不认为有一个常规适合开箱即用的,但你肯定可以找到一个


注意:如果要传递函数,它们不能是绑定函数,因为它们不可pickle,这是任务之间共享数据的要求。

进程可以简单地启动和终止

你可以这样做

import subprocess
watch = []
for s in ( "process1.py", "process2.py", "process3.py" ):
    sp = subprocess.Popen( s )
    watch.append( sp )
现在你只是在等待其中一个完成。当一个结束时,杀死其他人

import time
winner= None
while winner is None:
    time.sleep(10)
    for w in watch:
        if w.poll() is not None:
            winner= w
            break
for w in watch:
    if w.poll() is None: w.kill()
这些是进程,而不是线程。没有GIL考虑。让操作系统对它们进行调度;这就是它最擅长的


此外,每个过程都只是一个脚本,它使用您的一种替代算法简单地解决了问题。他们是完全独立的。设计、构建和测试都很简单。

是的,这就是为什么我也提到了子流程。:)是的,但问题是程序参数包括动态计算的函数(它们不是模块中的顶级函数,因此不可pickle)。子流程如何处理这些问题?@EOL:什么?您绝对必须能够编写一个独立的python脚本,以单向方式生成答案,对吗?将每个变体作为独立脚本编写。从配置文件或您只需导入的东西中获取参数。不要试图通过命令行界面将内容传递给子进程,这很有趣。@S.Lott。但是,计算的参数是数值函数,从简单的参数文件重建这些函数的成本相对较高,因此这种“配置文件”方法会降低速度。(具体来说,计算执行从许多数据点插值和外推的函数的卷积。每个过程都必须重新进行插值/外推,不是吗?)我希望Python会比这更强大。:)“每个过程都必须重新进行插值/外推?”我不知道怎么做,也不知道为什么。这些过程可以有一个共同的前端来创建这种“函数的卷积”,并创建各种解算器使用的中间结果集。在这一点上,您并不是在谈论多个进程,而是在其他进程完成时杀死一些进程。你说的是完全不同的事情。请打开一个新的问题,单独讨论这个复杂的业务,并有一些清晰和重点。感谢您的兴趣!我将尝试重用你的话:“解算器”是执行卷积运算的程序。换句话说,当前“前端”执行插值/外推并构建函数f和g。要执行的计算(通过不同的方法)是“在此间隔内卷积f和g”;这里,卷积程序的参数是不可pickle的函数。这就是为什么我认为您不必将这些函数传递给进程,而只需在卷积码中“重建”它们的数据。
多处理
在这种更复杂的情况下工作得非常好!实际上,我成功地将一个不可pickle的函数作为参数传递给了计算!我认为
多处理
只是
子进程
线程
的一个方便的包装,但在我看来,
多处理
提供了更多。PS:我确实检查了计算是否充分利用了这两个核心。