我有这段代码:
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
中的目录。
为什么第二个示例不是在rep1
和rep2
中创建目录?
答案 0 :(得分:5)
您正在寻找的答案详细解决here。还有一个不同操作系统差异的解释。
重大问题是Windows上不存在fork
系统调用。因此,在运行Windows操作系统时,您无法使用此方法。 multiprocessing
是执行当前正在运行的程序的一部分的更高级别接口。因此,它 - 像分叉一样 - 创建过程当前状态的副本。所以说,它会照顾你的程序分叉。
因此,如果可用,您可以考虑将fork()
作为分层程序的低级接口,并将多进程库作为分叉的更高级别接口。
希望这有帮助。
答案 1 :(得分:3)
要直接回答您的问题,external_process
必定会产生一些副作用,以便在代码串行运行时,您获得的结果与同时运行它们的结果不同。这是由于您设置代码的方式,以及支持os.fork
的系统中multiprocessing.Process
和os.fork
之间缺乏差异。
os.fork
和multiprocessing.Process
之间唯一真正的区别是可移植性和库开销,因为Windows中不支持os.fork
,并且包含multiprocessing
框架multiprocessing.Process
工作。这是因为os.fork
调用了multiprocessing.Process
,因为this answer进行了备份。
然后,重要的区别是os.fork
使用Unix的分支复制当前进程中的所有内容,这意味着在分叉时两个进程与PID差异相同。在Window中,通过重新运行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()
应该做同样的事情,但是从包含的多处理库中获得一些额外的开销。
如果没有进一步的信息,我们无法弄清问题是什么。如果您能提供演示此问题的代码,那将有助于我们为您提供帮助。