Является ли fork () копирование при записи стабильным открытым поведением, которое можно использовать для реализации разделяемой памяти только для чтения? - PullRequest
4 голосов
/ 08 сентября 2010

Страница man в fork () утверждает, что она не копирует страницы данных, она отображает их в дочерний процесс и ставит флаг копирования при записи. Это поведение:

  • согласуется между версиями Linux?
  • рассмотрены детали реализации и, следовательно, могут измениться?

Мне интересно, могу ли я использовать fork () в качестве средства, чтобы получить общий доступный только для чтения блок памяти по дешевке. Если физически скопировать память, это будет довольно дорого - происходит много разветвлений, и область данных достаточно велика - но я надеюсь, что нет ...

Ответы [ 5 ]

3 голосов
/ 09 сентября 2010

Да, вы, безусловно, можете положиться на ядра MMU-Linux;это почти все.

Однако размер страницы не везде одинаков.

Можно явно создать область разделяемой памяти для разветвленного процесса, используя mmap () для созданияанонимная карта - карта, которая не поддерживается физическим файлом.На вилке эта область всегда будет общей (при условии, что дочерний элемент не удаляет карту или отображает что-то еще по тому же адресу).Вы можете защитить его, чтобы он был доступен только для чтения, если хотите.

Память, выделенная (например) для malloc, может легко в конечном итоге разделить страницу с чем-то, что не доступно только для чтения, что означает, что она все равно копируется, когда другая структурамодифицирована.Это включает в себя внутренние структуры, используемые реализацией malloc.Таким образом, вы можете захотеть отобразить определенную область для этой цели и выделить из нее.

3 голосов
/ 08 сентября 2010

Linux, работающий на машинах без MMU (блока управления памятью), скопирует всю память процесса на fork ().

Однако эти системы обычно очень малы и встроены, и вам, вероятно, не нужно о них беспокоиться.

Многие службы, такие как модель вилки Apache, используют метод initialize и fork ()для совместного использования инициализированных структур данных.

Вы должны знать, что если вы используете такие языки, как Perl и Python, которые используют переменные с подсчетом ссылок, или C ++ shared_ptr, эта модель не будет работать.Это не сработает, потому что при увеличении и уменьшении количества ссылок память перестает делиться и копируется.

Это вызывает огромное использование памяти в демонах Perl, таких как SpamAssassin, которые пытаются использовать модель инициализации и ветвления.

2 голосов
/ 09 сентября 2010

Успех этого подхода зависит от того, насколько хорошо вы придерживаетесь своего добровольного ограничения «только для чтения».И родитель, и ребенок должны подчиняться этой строгости, иначе память копируется.

Однако, это может быть не та катастрофа, которую вы предполагаете.Ядро может скопировать всего одну страницу (обычно 4 КБ) для реализации семантики CoW.Типичный сервер Linux будет использовать что-то более сложное, своего рода распределитель плит , поэтому скопированная область может быть намного больше.

Суть в том, что это не связано с концепцией использования вашей программой памяти.Если у вас malloc() 1 ГБ ОЗУ, отключите дочерний элемент, а дочерний элемент изменит только первый байт этого блока памяти, весь блок размером 1 ГБ не будет скопирован.Возможно, копируется всего одна страница, вплоть до размера плиты, содержащего этот первый байт.

2 голосов
/ 08 сентября 2010

Можете ли вы полагаться на то, что все версии Linux делают это таким образом? Нет. Но вы можете положиться на тот факт, что те, кто не использует даже более быстрый метод.

Поэтому вы должны использовать эту функцию, полагаться на нее и пересмотреть свое решение, если у вас возникнут проблемы с производительностью.

1 голос
/ 08 сентября 2010

Да

Все дистрибутивы Linux используют одно и то же ядро, хотя и с немного разными версиями и выпусками.

Маловероятно, что другая базовая реализация fork (2) будет быстрее в ближайшее время, поэтому можно с уверенностью сказать, что копирование при записи будет оставаться механизмом. Возможно, это не будет вечно, но годами определенно.

Конечно, некоторые основные программные системы (например, Phusion Passenger ) используют fork (2) так же, как вы хотите, поэтому вы не единственный, кто использует CoW. *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...