Многопроцессорное копирование при записи в 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 здесь - просто обрабатывать его как поток, а не как кусок. Возможно, будет проще всего попытаться отправить столько данных, сколько вы можете, первому экземпляру, а затем посмотреть, когда он, наконец, выдаст ошибку, и использовать это как свой результат.