2009-08-25 3 views
1

Я знаю о «mmap», но насколько я знаю, хочу ли я обмениваться памятью, выделенной родительским процессом, и получить к ней доступ клиентский процесс мне нужно создать временный файл.Как я могу обмениваться памятью между родительско-дочерним процессом, который автоматически освобождает память, когда они умирают

Но этот файл будет продолжать существовать, если процессы умирают.

Я получил образование, чтобы не оставлять мусор позади. И в реальной жизни, и в программировании.

Решение должно работать на Linux, FreeBSD и Solaris.

ответ

0

Именованные трубы должны делать для вас, как указано выше. Вы можете использовать две трубы (если это возможно):

  1. parentpid_childpid - Родитель пишет и читает ребенок
  2. childpid_parentpid - пишет Ребенок и parebt читает.

Это работает для меня. Пожалуйста, укажите, есть ли у вас какие-либо особые сенарии.

2

Это article - очень хорошая отправная точка для совместной работы.

Однако я бы рекомендовал вам использовать трубу вместо этого, как правило, чтобы избежать условий гонки и всех умственных накладных расходов на параллелизм. Когда вы открываете дочерний процесс, его stdin и stdout являются файловыми дескрипторами, которые вы можете читать и записывать в родительский процесс.

+0

Извините, это небольшая и важная часть моего программного обеспечения, и мне нужно иметь возможность обмениваться наборами данных как можно быстрее. И я не боюсь о параллелизме и условиях гонки. Я люблю высокоскоростное параллельное программирование. Но здесь я должен вызвать внешний дочерний процесс, так как он может загружать небезопасные плагины, которые не должны были бы разбивать основное приложение. – Lothar

+2

Похоже, вы на вершине вещей, и статья, с которой я связан, будет иметь смысл. Вы в конечном итоге скопируете все, что родительский читает из общего буфера, в буфер, закрытый для родителя, а затем, конечно, проверьте его. И в какой-то момент вы попытаетесь сделать в userland то, что ядро ​​делает для вас с помощью труб, и вы, возможно, не найдете трубы настолько медленными. – Will

0

Выделить память в родительском. Используйте эту память как в родительском, так и в Child. Предоставьте освобождение памяти родительскому объекту. Сделать родительский wait (wait системный вызов) дочернего элемента. Родитель освобождает память перед выходом.

В качестве альтернативы быть на более безопасной стороне, прежде чем ребенок выйдет, проверьте, жив ли он или нет. Если нет, освободите память у самого ребенка. Но это не сработает, если может быть несколько дочерних.

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

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

1

Mmap обычно поддерживает «анонимный» режим, который не создает никакого мусора. Он работает на LInux, согласно man-странице, работающей на Solaris, я не уверен в FreeBSD - посмотрите на страницу man и найдите MAP_ANON или MAP_ANONYMOUS.

+1

И я должен добавить это перед MAP_ANONYMOUS, трюк, используемый для отключения() файла сразу после mmap. Это позволяет родительскому и дочернему процессам использовать общую память. – ondra

+0

Хм, если я использую MAP_ANONYMOUS, какой файловый дескриптор должен пройти, если не файл? Хорошо, я могу попытаться создать файл «/ tmp/dummy», чтобы использовать дескриптор (который никогда не записывается). Но он все еще оставляет мусор. – Lothar

+0

Вы передаете '-1' в качестве дескриптора файла при использовании' MAP_ANONYMOUS'. – caf

0

Используйте POSIX shm_open (3) и связанные функции для отображения памяти, не поддерживаемой файлом. Дескриптор файла, возвращаемый shm_open(), должен автоматически закрываться, если родитель и ребенок перестают существовать, но я не уверен на 100%, если это всегда так. Может быть, кто-то еще может пролить свет на это?

+0

Извините «shm», и семафоры posix настолько сломаны на FreeBSD (shm по дизайну - как я узнал после разговора в списке рассылки FreeBSD). – Lothar

0

Выделите память в родительском процессе, подождите, пока дочерний процесс выполнит или разрешит ему выполнять другие задачи.Как только дочерний процесс закончится, он вернется к родительскому процессу, Отмените там память.

Если родительский процесс необходимо остановить до того, как ребенок (в этом случае ребенок считается сиротой), используйте exec(), который начнет дочерний процесс как новый процесс.

Смежные вопросы