如何在多个计算并行时,在第一个返回时停止所有计算?[Python]
如何让多个计算同时进行,并在第一个计算完成后停止其他所有计算呢?
我想的这个应用场景是这样的:我们有多种方法来计算一个特定的值;每种方法所需的时间不同,取决于函数的参数。如果我们同时启动这些计算,最快的那个计算就会自动被“选中”,而其他的计算会被停止。
不过,这里有一些细节让这个问题变得更复杂:
- 要计算的函数的参数中包含了函数(这些函数是根据数据点计算出来的,不是顶层模块的函数)。实际上,这个计算是两个函数的卷积。我不太确定这样的函数参数怎么能传递给子进程(因为它们不能被序列化)。
- 我无法访问所有的计算代码:有些计算是由Scipy内部完成的(可能是通过Fortran或C代码)。我不太确定线程是否提供类似于可以发送给进程的终止信号的功能。
这在Python中是否比较容易实现呢?
3 个回答
0
因为有一个叫做全局解释器锁的东西,你很难通过这种方式提高速度。实际上,即使是多线程的程序在Python中也只会在一个核心上运行。所以,你实际上只是用N个进程以1/N的速度在运行。即使其中一个进程的完成时间是其他进程的一半,从整体来看你还是会浪费时间。
0
进程可以很简单地启动和结束。
你可以这样做。
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)的问题。让操作系统来安排它们的运行;这是它最擅长的事情。
另外,每个进程就是一个脚本,利用你的一种替代算法来解决问题。它们完全独立,互不干扰。设计、构建和测试都很简单。
1
如果你还没看过的话,可以了解一下multiprocessing
模块。这个模块可以让你把任务分配到不同的进程去处理,同时它的使用方式和threading
模块很像,简单易懂。
它提供了和threading
模块类似的基本功能,比如工作池和队列,这些可以用来在任务之间传递消息。不过,使用这个模块的好处是,你的任务是在不同的进程中运行的,这样就可以避免GIL(全局解释器锁)的问题。
你想要的具体功能可能比较特殊,所以我觉得没有现成的解决方案完全符合你的需求,但你肯定可以自己动手实现一个。
注意:如果你想传递函数,它们不能是绑定函数,因为绑定函数不能被序列化(pickle),而这是在任务之间共享数据的一个要求。