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

Я пытаюсь разделить объекты между родительским и дочерним процессами в 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 SMP x86_64 GNU/Linux), я получаю следующий вывод:

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

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

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

2 ответа

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

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

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

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

OSX и Ubuntu по-разному обрабатывают кэш принтера. Весьма вероятный OSX здесь - просто обрабатывать его как поток, а не как кусок. Возможно, будет проще всего попытаться отправить столько данных, сколько вы можете, первому экземпляру, а затем посмотреть, когда он, наконец, выдаст ошибку, и использовать это как свой результат.

Другие вопросы по тегам