Совместное использование памяти между процессами с помощью mmap () - PullRequest
20 голосов
/ 14 февраля 2011

Я в Linux 2.6.У меня есть среда, в которой 2 процесса имитируют (используя общую память) обмен данными через простую реализацию режима передачи сообщений.

У меня есть клиентский процесс (разветвленный от родителя, который является сервером), которыйзаписывает структуру (сообщение) в область отображения памяти, созданную (после разветвления) с помощью:

message *m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)

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

Проблема в том, что * m создается после fork () и когда процесс сервера пытается получить доступ к указанному месту в памятия получаю ошибку сегментации.Можно ли присоединить эту область памяти к разветвлению POST сервера после того, как клиент его создаст?

ПРИМЕЧАНИЕ. Я не хочу отображать указатель на сообщение перед разветвлением (а затем делиться им досервер), потому что я обычно не знаю, сколько сообщений клиент хочет отправить на сервер, а также может быть более одного клиентского процесса, поэтому я хотел бы создать новый блок разделяемой памяти только тогда, когда клиенту нужноотправить сообщение и распаковать его после того, как сервер получил это сообщение.

ПРИМЕЧАНИЕ.путь.

Заранее спасибо!

Ответы [ 3 ]

28 голосов
/ 14 февраля 2011

Можно ли присоединить эту область памяти к разветвлению POST сервера после того, как клиент ее создаст?

MAP_ANONYMOUS|MAP_SHARED отображенная память может быть доступна только процессу, который выполняет этот вызов mmap(), или его дочерним процессам. Другой процесс не может отобразить ту же память, поскольку на эту память нельзя ссылаться откуда-либо еще, поскольку она является анонимной .

Используя shm_open() вызов, можно создать с именем разделяемой памяти, к которой можно обращаться и отображать несвязанные процессы.

8 голосов
/ 13 февраля 2018

Просто для тех, кто читает этот вопрос в 2018 году и позже.Теперь решение состоит в том, чтобы использовать memfd_create для создания анонимного файла и использовать сокет unix для передачи этого дескриптора файла другому процессу.

memfd_create - это системный вызов только для linux

6 голосов
/ 14 февраля 2011

Это не сработает.

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

Вы не можете предполагать совместное использование указателей таким образом.

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

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

...