OSX和Ubuntu之间的Python多处理写入时复制行为不同

时间:2018-12-18 21:49:38

标签: python linux shared-memory python-multiprocessing copy-on-write

我正在尝试在Python的父进程和子进程之间共享对象。为了解决这个问题,我创建了一个简单的Python脚本:

from multiprocessing import Process
from os import getpid

import psutil

shared = list(range(20000000))

def shared_printer():
    mem = psutil.Process(getpid()).memory_info().rss / (1024 ** 2)
    print(getpid(), len(shared), '{}MB'.format(mem))

if __name__ == '__main__':
    p = Process(target=shared_printer)
    p.start()
    shared_printer()
    p.join()

该代码段使用了出色的psutil库来打印RSS(居民集大小)。当我在使用Python 2.7.15的OSX上运行此命令时,得到以下输出:

(33101, 20000000, '1MB')
(33100, 20000000, '626MB')

当我在Ubuntu(Linux 4.15.0-1029-aws#30-Ubuntu SMP x86_64 GNU / Linux)上运行完全相同的代码段时,得到以下输出:

(4077, 20000000, '632MB')
(4078, 20000000, '629MB')

请注意,子进程的RSS在OSX上基本为0MB,大小与Linux中的父进程的RSS相同。我曾假设写时复制行为在Linux中将以相同的方式工作,并且允许子进程在大多数页面(也许除了存储对象头部的那个页面)引用父进程的内存。

因此,我猜测两个系统中的“写时复制”行为有所不同。我的问题是:我可以在Linux中做些什么来获得类似OSX的写时复制行为吗?

2 个答案:

答案 0 :(得分:2)

  

因此,我猜测这两个系统中的“写时复制”行为有所不同。我的问题是:在Linux中我可以做些什么来>获得类似于OSX的写时复制行为?

答案是。操作系统在命令psutil.Process(getpid()).memory_info().rss / (1024 ** 2)后面使用UNIX命令$top [PID]并搜索字段RES。其中包含任务已在 kb 中使用的未交换物理内存。即RES =代码+数据。

恕我直言,这意味着两个操作系统都使用不同的内存管理器。因此,几乎不可能限制一个进程使用/需要多少内存。这是操作系统的一个内部问题。 在Linux中,子进程的大小与父进程的大小相同。实际上,它们复制相同的堆栈,代码和数据。但是使用不同的PCB(过程控制块)。因此,不可能像OSX那样接近0。闻到OSX并没有从字面上复制代码和数据。如果它们是相同的代码,它将使指针指向父进程的数据。

PD:希望对您有帮助!

答案 1 :(得分:-2)

OSX和ubuntu处理打印机缓存的方式不同。这里很有可能的OSX只是将其作为流而不是块来处理。尝试将尽可能多的邮件发送到第一个实例,然后查看它最终何时出错并将其用作结果,这可能是最容易的。