Многопроцессорное копирование при записи в Python ведет себя по-разному в OSX и Ubuntu - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь разделить объекты между родительским и дочерним процессами в 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 (Resident Set Size).Когда я запускаю это на OSX с Python 2.7.15, я получаю следующий вывод:

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

Когда я запускаю точно такой же фрагмент в Ubuntu (Linux 4.15.0-1029-aws # 30-Ubuntu SMPx86_64 GNU / Linux), я получаю следующий вывод:

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

Обратите внимание на то, что RSS-файл дочернего процесса в ОС OSX равен 0 МБ и примерно такого же размера, что и родительский процесс RSS в Linux.Я предполагал, что поведение копирования при записи будет работать в Linux таким же образом и позволит дочернему процессу обращаться к памяти родительского процесса для большинства страниц (возможно, за исключением той, которая хранит заголовок объекта).

Итак, я предполагаю, что есть некоторое различие в поведении копирования при записи в двух системах.У меня такой вопрос: могу ли я что-нибудь сделать в Linux, чтобы получить подобное OSX-поведение при копировании при записи?

1 Ответ

0 голосов
/ 28 декабря 2018

Так что я предполагаю, что есть некоторое различие в поведении копирования при записи> в 2 системах.Мой вопрос: Есть ли что-нибудь, что я могу сделать в Linux, чтобы> получить такое OSX-подобное поведение копирования при записи?

Ответ: НЕТ .За командой psutil.Process(getpid()).memory_info().rss / (1024 ** 2) ОС использует команду UNIX $top [PID] и ищет поле RES.Содержит физическую память без перестановки, которую задача использовала в kb .т.е. RES = КОД + ДАННЫЕ.

ИМХО, это означает, что обе ОС используют разные менеджеры памяти.Таким образом, почти невозможно ограничить, сколько памяти использует процесс.Это внутренняя проблема ОС.В Linux дочерний процесс имеет такой же размер родительского процесса.Действительно, они копируют один и тот же стек, код и данные.Но разные PCB (блок управления процессом).Поэтому невозможно приблизиться к 0, как это делает OSX.Пахнет, что OSX буквально не копирует код и данные.Если они представляют собой один и тот же код, он сделает указатель на данные родительского процесса.

PD: Я надеюсь, что это поможет вам!

...