我在理解这里发生的事情时遇到了一些麻烦。我想使用多处理模块并行运行一些子进程调用。
我的简单示例基本上是调用等待5秒的函数,打印输出然后在终止之前等待另外5秒。
我希望函数被锁定,直到它打印出一行代码(真的是任何东西),然后允许其他进程继续工作。
以下是插图:
import time
import subprocess
import multiprocessing as mp
def main(l):
l.acquire()
#Lock process while it is run
proc = subprocess.Popen("python script_test.py", stdout=subprocess.PIPE)
#Wait until one byte is read then release
proc.stdout.read(1)
l.release()
#Terminate process when it has completed
proc.poll()
if __name__ == "__main__":
#Initialize lockiing mechanism
manager = mp.Manager()
lock = manager.Lock()
#Split up subprocess calls
ncpu = mp.cpu_count()
p = mp.Pool(ncpu)
p.map(main, [lock]*ncpu)
print "Run time = {0}s using {1} processes on {2}.".format(time.time()-start, ncpu, ncpu)
script_test.py
的内容如下:
import time
#Do some work up until the point of the print statement
time.sleep(5)
print "Okay 5 seconds has passed!"
#Continue doing work while allowing other processes to proceed
time.sleep(5)
好像这不是并行运行的。对于ncpu
等于4的情况,总时间需要40.7秒,但是应该只有大约5*ncpu + 5*2 = 25
加上开销,因为前5秒被锁定而最后5个不应该用于每个进程。
我正在运行script_test.py
作为示例,但实际上这将是一个可执行文件。
我的问题是:
答案 0 :(得分:1)
由于您错误地使用了单个共享锁,因此您已将代码转换为串行执行。发生的事情是你的一个进程获得了锁定,其他三个进程正在等待第一个进程执行。第一个进程完成后,下一个进程抓取锁并运行脚本,而另外两个进程等待(依此类推)。所以,你创建了四个进程,但是你只是按照你使用锁的方式运行它们。从你的代码中,我认为你真的不需要锁。这些进程并不真正共享数据,因为每个subprocess.Popen调用都是它自己的实例。
子进程还有另一个执行脚本的进程,你需要使用子进程方法来读取脚本的“stdout”,然后重新打印出来。使用“check_output”之类的调用,而不是调用Popen,将它们保存到变量并打印。
编辑 - 问题1已经改变 - 新答案: