8

I have this code :

import os

pid = os.fork()

if pid == 0:
    os.environ['HOME'] = "rep1"
    external_function()
else:
    os.environ['HOME'] = "rep2"
    external_function()

and this code :

from multiprocessing import Process, Pipe

def f(conn):
    os.environ['HOME'] = "rep1"
    external_function()
    conn.send(some_data)
    conn.close()

if __name__ == '__main__':
    os.environ['HOME'] = "rep2"
    external_function()
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print parent_conn.recv()
    p.join()

The external_function initializes an external programs by creating the necessary sub-directories in the directory found in the environment variable HOME. This function does this work only once in each process.

With the first example, which uses os.fork(), the directories are created as expected. But with second example, which uses multiprocessing, only the directories in rep2 get created.

Why isn't the second example creating directories in both rep1 and rep2?

4

2 回答 2

11

您正在寻找的答案在此处详细介绍。还有一个解释不同操作系统之间的差异。

一个大问题是fork系统调用在 Windows 上不存在。因此,在运行 Windows 操作系统时,您不能使用此方法。multiprocessing是执行当前正在运行的程序的一部分的更高级别的接口。因此,它 - 就像分叉一样 - 创建您的流程当前状态的副本。也就是说,它会为您处理程序的分叉。

因此,如果可用,您可以考虑fork()使用较低级别的接口来分叉程序,而multiprocessing库是更高级别的分叉接口。

于 2014-06-04T16:19:03.737 回答
3

要直接回答您的问题,必须有一些副作用,external_process这样当代码串联运行时,您会得到与同时运行它们不同的结果。这是由于您设置代码的方式,以及受支持的系统之间os.forkmultiprocessing.Process系统之间缺乏差异。os.fork


os.fork和之间唯一真正的区别multiprocessing.Process是可移植性和库开销,因为os.fork在 Windows 中不受支持,并且multiprocessing包含框架以使其multiprocessing.Process工作。这是因为os.fork由 调用multiprocessing.Process,因为这个答案支持。

因此,重要的区别是os.fork使用 Unix 的分叉复制当前进程中的所有内容,这意味着在分叉时两个进程相同,但 PID 不同。在 Window 中,这是通过重新运行 之前的所有设置代码来模拟的,这与使用库if __name__ == '__main__':创建子进程大致相同。subprocess

对您来说,您提供的代码片段在上面做了完全不同的事情,因为您external_function在打开第二个代码片段中的新进程之前调用 main ,使两个进程串联但在不同的进程中运行。管道也是不必要的,因为它没有模拟第一个代码的功能。

在 Unix 中,代码片段:

import os

pid = os.fork()

if pid == 0:
    os.environ['HOME'] = "rep1"
    external_function()
else:
    os.environ['HOME'] = "rep2"
    external_function()

和:

import os
from multiprocessing import Process

def f():
    os.environ['HOME'] = "rep1"
    external_function()

if __name__ == '__main__':
    p = Process(target=f)
    p.start()
    os.environ['HOME'] = "rep2"
    external_function()
    p.join()

应该做完全相同的事情,但是包含的多处理库会带来一些额外的开销。


没有更多信息,我们无法弄清楚问题所在。如果您可以提供演示该问题的代码,那将有助于我们为您提供帮助。

于 2014-06-04T16:09:42.510 回答