gpt4 book ai didi

python - 多处理和全局文件句柄的奇怪行为

转载 作者:太空宇宙 更新时间:2023-11-03 15:08:58 34 4
gpt4 key购买 nike

有人可以帮我理解下面的代码片段吗?我知道我不能使用多处理来使用全局变量,但我仍然对我看到的结果感到惊讶。

我在不同工作进程中远程执行的函数中使用全局文件句柄。

import multiprocessing
import os

fh = open("out.txt", "w")

def process(i):
print("i={} pid={} id(fh)={}".format(i, os.getpid(), id(fh)))
print(i, file=fh)

def main():
p = multiprocessing.Pool(3)
p.map(process, (1, 2, 3))
p.terminate()
fh.close()

main()

输出为

i=1  pid=92045  id(fh)=4314964256
i=2 pid=92046 id(fh)=4314964256
i=3 pid=92047 id(fh)=4314964256

因此我们看到,正如预期的那样,存在三个不同的进程 ID。

令我惊讶的是:

  1. 不可选取的文件句柄在工作进程中可用
  2. id计算出的内存地址对于所有worker都是相同的
  3. 工作进程可以写入此文件句柄而不引发异常
  4. 尽管如此,程序执行后该文件还是空的。

最佳答案

我自己找到了答案:

  1. 不可选取的文件句柄在工作进程中可用:来自 Python 解释器进程和全局变量的多处理分支因此被复制到内存中(SO post multiprocessing global variable memory copying ) 。仅当在子解释器中调用函数时,才会对函数参数进行变量的pickle。
  2. 由 id 计算的内存地址对于所有工作线程都是相同的:显示的内存地址是虚拟地址空间内的地址,因此是相对的。 fork 后,初始内存布局是相同的。 (所以帖子Fork - same memory addresses?)
  3. 工作进程可以写入此文件句柄而不引发异常:请参阅答案 1 +对于 fork 进程,fh 的底层 fileno 是相同的。
  4. 尽管如此,程序执行后文件为空:如果我在从 process 返回之前调用 flush 方法,则文件不为空。因此,当进程被其父进程杀死时,文件缓冲区不会被刷新。

备注:我的示例在 Windows 上的表现应该有所不同。由于不同的进程模型/实现,Windows 上的多处理必须启动新的 Python 解释器。

关于python - 多处理和全局文件句柄的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44395588/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com