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之间有一个抽象层,那么细节是很重要的。