Python os.fork和multiprocessing.Process之间的行为差异

Python os.fork和multiprocessing.Process之间的行为差异,python,process,multiprocessing,fork,python-multiprocessing,Python,Process,Multiprocessing,Fork,Python Multiprocessing,我有以下代码: 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'] = "

我有以下代码:

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()
该代码:

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

在第一个示例中,使用了
os.fork()
,目录按预期创建。但在第二个示例中,使用了
多处理
,只创建了
rep2
中的目录


为什么第二个示例不在
rep1
rep2
中创建目录?

要直接回答您的问题,必须有
外部\u过程的一些副作用,这使得在串联运行代码时,得到的结果与同时运行它们时不同。这是由于您如何设置代码,以及在支持
os.fork
的系统中
os.fork
multi-processing.Process
之间缺乏差异


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

因此,重要的区别是
os.fork
使用Unix的forking复制当前进程中的所有内容,这意味着在forking时,两个进程是相同的,但存在PID差异。在窗口中,通过重新运行
之前的所有设置代码(如果uuu name\uuuu=='\uuu main\uuuu':
)来模拟这一点,这与使用
子流程
库创建子流程大致相同

对于您来说,您提供的代码片段所做的事情与上面完全不同,因为在第二个代码片段中打开新进程之前,您在main中调用了
external\u function
,这使得两个进程串联运行,但在不同的进程中运行。此外,管道是不必要的,因为它不模拟来自第一个代码的任何功能

在Unix中,代码段包括:

import os

pid = os.fork()

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

应该做完全相同的事情,但是从包含的多处理库中获得一点额外的开销



如果没有进一步的信息,我们无法找出问题所在。如果您能提供演示该问题的代码,我们将为您提供帮助。

您正在寻找的答案已详细说明。对于不同操作系统之间的差异也有解释

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


因此,如果可用的话,可以考虑<代码> FoK()/Case>一个低级接口来分叉程序,而多重处理库是一个更高级别的分叉接口。

我不能重现你所看到的问题。我编写了一个
external_函数
如下:
def external_函数():print os.environ['HOME']
,发现
多处理
示例输出的正是我所期望的;'“rep1”、“rep2”和我从
conn.send
发回的字符串都被打印出来了。我想你会找到答案的。我执行的函数是
getInstalledPackages
from.@andi这就是我怀疑的。如果你写一个答案,我会接受的,我会这么做的。给我一分钟。Dano的示例与我的函数不一样。但他的评论仍然有效,如果没有您的输入,我们无法复制您遇到的行为。如果您想复制我遇到的行为,您必须安装一组软件包。如果Dano的编辑是正确的,如果你不知道软件包的名称,我们就无法回答你的问题。如果你知道它们之间的区别,你可以回答我的问题。请注意,如果其他人有与上述用户相同的问题,此答案只提供另一个链接。如果你能按照社区指导方针的要求,在回答中提供相关信息,我将取消我的否决票。我希望这就是你的要求。否则让我知道。谢谢你的批评。它实际上并没有在Windows中创建当前进程的副本。否则,列出的所有警告都不会成为问题。请参阅我的答案以了解更多详细信息。“为您处理分叉”。。。如果我的程序在锁内分叉怎么办。预计会出现僵局吗?如果在我和forking之间有一个抽象层,那么细节是很重要的。