Yib*_*ang 4 python parallel-processing multiprocessing python-multiprocessing
从这个问题我了解到:
当您使用多处理打开第二个进程时,会创建一个全新的 Python 实例,具有自己的全局状态。该全局状态不共享,因此子进程对全局变量所做的更改对于父进程来说是不可见的。
为了验证这种行为,我制作了一个测试脚本:
import time
import multiprocessing as mp
from multiprocessing import Pool
x = [0] # global
def worker(c):
if c == 1: # wait for proc 2 to finish; is global x overwritten by now?
time.sleep(2)
print('enter: x =', x, 'with id', id(x), 'in proc', mp.current_process())
x[0] = c
print('exit: x =', x, 'with id', id(x), 'in proc', mp.current_process())
return x[0]
pool = Pool(processes=2)
x_vals = pool.map(worker, [1, 2])
print('parent: x =', x, 'with id', id(x), 'in proc', mp.current_process())
print('final output', x_vals)
Run Code Online (Sandbox Code Playgroud)
输出(在 CPython 上)类似于
enter: x = [0] with id 140138406834504 in proc <ForkProcess(ForkPoolWorker-2, started daemon)>
exit: x = [2] with id 140138406834504 in proc <ForkProcess(ForkPoolWorker-2, started daemon)>
enter: x = [0] with id 140138406834504 in proc <ForkProcess(ForkPoolWorker-1, started daemon)>
exit: x = [1] with id 140138406834504 in proc <ForkProcess(ForkPoolWorker-1, started daemon)>
parent: x = [0] with id 140138406834504 in proc <_MainProcess(MainProcess, started)>
final output [1, 2]
Run Code Online (Sandbox Code Playgroud)
id我该如何解释ofx在所有进程中共享,但x取不同值的事实?从概念上讲,这不是idPython对象的内存地址吗?我想如果内存空间在子进程中被克隆,这是可能的。那么有什么东西可以用来获取Python对象的实际物理内存地址吗?
共享状态
当您使用多处理打开第二个进程时,会创建一个全新的 Python 实例,具有自己的全局状态。该全局状态不共享,因此子进程对全局变量所做的更改对于父进程来说是不可见的。
这里的关键点似乎是:
这个全球状态不是共享的……”
...指的是子进程的全局状态。但这并不意味着父进程的部分全局状态不能与子进程共享,只要子进程不尝试写入该部分即可。当这种情况发生时,这部分将被复制和更改,并且对父级不可见。
背景:
在 Unix 上,“fork”是启动子进程的默认方式:
父进程使用 os.fork() 来 fork Python 解释器。子进程在启动时实际上与父进程相同。父进程的所有资源都被子进程继承。请注意,安全分叉多线程进程是有问题的。
仅适用于 Unix。Unix 上的默认值。
Fork 是使用copy-on-write实现的,因此除非您分配一个新对象,否则x不会发生复制,并且子进程与其父进程共享相同的列表。
内存地址
我该如何解释 x 的 id 在所有进程中共享,但 x 取不同值的事实?
Fork 创建一个子进程,其中的虚拟地址空间与父进程的虚拟地址空间相同。虚拟地址将全部映射到相同的物理地址,直到发生写时复制。
现代操作系统使用虚拟寻址。基本上,您在程序中看到的地址值(指针)不是实际的物理内存位置,而是指向索引表(虚拟地址)的指针,而索引表又包含指向实际物理内存位置的指针。由于这种间接性,如果虚拟地址属于不同进程的索引表,则可以使相同的虚拟地址指向不同的物理地址。关联
那么有什么东西可以用来获取Python对象的实际物理内存地址吗?
There doesn't seem to be a way to get the actual physical memory address (link). id returns the virtual (logical) memory address (CPython). The actual translation from virtual to physical memory address falls to the MMU.