【问题标题】:Why do processes spawned by the multiprocessing module not duplicate memory?为什么多处理模块产生的进程不复制内存?
【发布时间】:2015-03-20 08:29:31
【问题描述】:

我对 python 多处理的印象是,当您使用 multiprocessing.Process() 创建一个新进程时,它会在内存中创建当前程序的完整副本并从那里继续工作。考虑到这一点,我对以下脚本的行为感到困惑。

警告:此脚本将分配大量内存!谨慎运行!

import multiprocessing
import numpy as np
from time import sleep

#Declare a dictionary globally
bigDict = {}

def sharedMemory():
    #Using numpy, store 1GB of random data
    for i in xrange(1000):
        bigDict[i] = np.random.random((125000))
    bigDict[0] = "Known information"

    #In System Monitor, 1GB of memory is being used
    sleep(5)

    #Start 4 processes - each should get a copy of the 1GB dict
    for _ in xrange(4):
        p = multiprocessing.Process(target=workerProcess)
        p.start()

    print "Done"

def workerProcess():
    #Sleep - only 1GB of memory is being used, not the expected 4GB
    sleep(5)

    #Each process has access to the dictionary, even though the memory is shared
    print multiprocessing.current_process().pid,bigDict[0]

if __name__ == "__main__":
    sharedMemory()

上面的程序说明了我的困惑 - 似乎 dict 自动在进程之间共享。我认为要获得这种行为,我必须使用多处理管理器。有人可以解释发生了什么吗?

【问题讨论】:

  • 你在哪个操作系统上?
  • Ubuntu 14.04 64 位和 Python 2.7.6。

标签: python multiprocessing


【解决方案1】:

在 Linux 上,分叉一个进程不会导致立即占用两倍的内存。相反,新进程的页表将被设置为指向与旧进程相同的物理内存,并且只有当其中一个进程尝试写入其中一个页面时,它们才会被实际复制(copy on写,牛)。结果是两个进程似乎都有单独的内存,但只有在其中一个进程实际接触到内存时才分配物理内存。

【讨论】:

  • 好吧,这很有道理。但是,在workerProcess()的开头,我添加了bigDict[5] = multiprocessing.current_process().pid这一行,然后打印出来,发现每个进程都存储了正确的id,但内存仍然没有增加。在像我正在使用的那样的字典中,它是否分别处理每个元素? (也就是说,只是复制了 bigDict[5],而不是整个内容?)。
  • 字典,就像 Python 中的大多数容器一样,只存储对其元素的引用,而不是元素的副本。
  • @TheBeardedTemplar:就操作系统而言,内存的粒度是pages,在Linux上通常是4KB。操作系统对进程选择存储在该内存中的数据结构一无所知。您描述的单个更改预计会使内存使用量增加 4 KB。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-19
  • 2021-05-05
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
相关资源
最近更新 更多