os.fork和multiprocessing.Process的行为差异

2024-06-28 20:15:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这个密码:

import os

pid = os.fork()

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

这个代码:

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()

external_function通过在环境变量HOME中找到的目录中创建必要的子目录来初始化外部程序。此函数在每个进程中仅执行一次此操作。

对于第一个使用os.fork()的示例,将按预期创建目录。但是在使用multiprocessing的第二个示例中,只创建rep2中的目录。

为什么第二个示例不同时在rep1rep2中创建目录?


Tags: import目录示例homeifosenvironfunction
2条回答

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


os.forkmultiprocessing.Process之间唯一真正的区别是可移植性和库开销,因为在windows中不支持os.fork,并且包含multiprocessing框架来使multiprocessing.Process工作。这是因为os.forkmultiprocessing.Process调用,作为this answer备份。

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

对您来说,您提供的代码片段执行的是完全不同的上述操作,因为在第二个代码片段中打开新进程之前,您在main中调用了external_function,使这两个进程在不同的进程中串联运行。此外,管道是不必要的,因为它没有从第一个代码中模拟任何功能。

在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()

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


如果没有进一步的信息,我们就无法找出问题所在。如果你能提供代码来演示这个问题,那将有助于我们帮助你。

你要找的答案是详细写好的here。此外,还解释了不同操作系统的差异。

最大的问题是,fork系统调用在windows上不存在。因此,在运行windows操作系统时,不能使用此方法。multiprocessing是一个高级接口,用于执行当前运行的程序的一部分。因此,正如forking所做的那样,它会创建进程当前状态的副本。所以说,它关心你的程序的分叉。

因此,如果可以的话,可以考虑fork()一个低级接口来派生程序,而多进程库是高级接口来派生程序。

希望这有帮助。

相关问题 更多 >