多处理:为什么我的进程没有并行运行?

时间:2015-01-23 02:42:26

标签: python parallel-processing multiprocessing

我在理解这里发生的事情时遇到了一些麻烦。我想使用多处理模块并行运行一些子进程调用。

我的简单示例基本上是调用等待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作为示例,但实际上这将是一个可执行文件。

我的问题是:

  1. 如何正确使用锁来完成上述操作?
  2. 我从命令提示符运行脚本,但我没有看到任何输出。如何从多处理模块启动的子进程中打印子进程的输出?

1 个答案:

答案 0 :(得分:1)

  1. 由于您错误地使用了单个共享锁,因此您已将代码转换为串行执行。发生的事情是你的一个进程获得了锁定,其他三个进程正在等待第一个进程执行。第一个进程完成后,下一个进程抓取锁并运行脚本,而另外两个进程等待(依此类推)。所以,你创建了四个进程,但是你只是按照你使用锁的方式运行它们。从你的代码中,我认为你真的不需要锁。这些进程并不真正共享数据,因为每个subprocess.Popen调用都是它自己的实例。

  2. 子进程还有另一个执行脚本的进程,你需要使用子进程方法来读取脚本的“stdout”,然后重新打印出来。使用“check_output”之类的调用,而不是调用Popen,将它们保存到变量并打印。

  3. 编辑 - 问题1已经改变 - 新答案:

    1. 您必须从更基础的层面看待当前的问题。如果我正确理解您的评论,听起来您的进程正在同一个文本文件上运行,该文件既被修改又被阅读。你不能并行操作(至少不是很好),因为你会不断地锁定它。如果您可以创建单独的文本文件,如某种单独的输出名称,那么您可以开始使事情并行运行。我不知道你的可执行文件到底在做什么,所以很难说。您还需要在代码的修改部分和读取部分的不同区域调用锁定,这可能需要您将此测试脚本导入到多处理脚本中。如果修改和写入操作绑定在可执行文件中(并且无法创建单独的文本文件),那么您将很难解决此问题。