Общая память: давайте поговорим о ее специфике - PullRequest
0 голосов
/ 31 января 2020

Рассмотрим следующий псевдокод между двумя процессами P1 и P2 :
В процессе P1:

struct SharedStruct
{
    int i;
    void *pData;
};

HANDLE hMapFile = CreateFileMapping("Global\\MyFileMappingObject")  
LPCTSTR pBuf = (LPTSTR) MapViewOfFile(hMapFile, ...) 

SharedStruct mySharedStruct;
mySharedStruct.i=33;

mySharedStruct.pData = (void*) calloc (1, 10);

memcpy ( (void*) pBuf, (void*) (&mySharedStruct), sizeof (mySharedStruct));  

В процессе P2:

hMapFile hMapFile = OpenFileMapping("Global\\MyFileMappingObject")  
SharedStruct *pSharedStruct_P2 = (SharedStruct *) MapViewOfFile (hMapFile,...)
...  

Проблема:
pSharedStruct_P2-> pData является локальной памятью P1 адрес , который не может использоваться P2

Reflection:
- это использование общей памяти, ограниченное только типами basi c (int, плавать, ...)? или для совместного использования локальных адресов используется другой общий доступ к памяти?

1 Ответ

0 голосов
/ 31 января 2020

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

struct Foo {
    double a;
    double b;
    double* a_or_b;
};

Foo x{1, 2, nullptr};
x.a_or_b = &a;

Вы можете сделать это:

struct Foo {
    double  a;
    double  b;
    ptrdiff_t a_or_b;
};

Foo x{1, 2, 0};
x.a_or_b = static_cast<const char*>(&a) - static_cast<const char*>(&a_or_b);

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

В boost.interprocess есть контейнеров, вдоль строк std :: string и std :: map, которые работают внутренне. Они существуют именно для того, чтобы вы могли использовать их в такой ситуации. Эта библиотека имеет множество других полезных средств для управления разделяемой памятью, которые вы можете использовать в любом случае sh, такие как независимые от платформы API для отображения разделяемой памяти и мьютексов между процессами.

Другие библиотеки такого типа формы смещения: FlatBuffers и Cap'n Proto . В этих случаях мотивация для использования внутренних смещений немного отличается (так что сериализация на диск или в сеть точно такая же, как в представлении в памяти), но все равно будет хорошо работать для общей памяти.

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