Обмен памятью между процессами с помощью mmap()

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

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

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

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

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

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

ПРИМЕЧАНИЕ. Это для академической цели: я знаю, что это не лучший способ решить эту проблему, но мне просто нужно следовать этому пути.

Спасибо заранее!

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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