Как выбрать фиксированный адрес для mmap? - PullRequest
10 голосов
/ 23 июня 2011

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

Есть ли область памяти, которую Linux гарантирует неиспользованной (приложением)и ядром) что я могу сопоставить?Как найти один адрес, доступный в нескольких запущенных приложениях?

Ответы [ 3 ]

7 голосов
/ 23 июня 2011

Не совсем, нет. При рандомизации адресного пространства в современных системах Linux очень сложно гарантировать, что адреса могут или не могут использоваться.

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

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

3 голосов
/ 14 июня 2012

Два процесса могут отобразить блок общей памяти на один и тот же виртуальный адрес, используя shm_open () и mmap (); то есть виртуальный адрес, возвращаемый из mmap (), может быть одинаковым для обоих процессов. Я обнаружил, что Linux по умолчанию будет предоставлять разные виртуальные адреса разным процессам для одного и того же фрагмента общей памяти, но использование mmap () с MAP_FIXED заставит Linux предоставлять один и тот же виртуальный адрес нескольким процессам.

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

Мне удалось использовать общую память для этого. При этом «золотой» виртуальный адрес сохраняется в блоке общей памяти; Я создал структуру, содержащую несколько элементов, одним из которых является адрес, и инициализировал ее в начале блока.

Процесс, который хочет отобразить эту совместно используемую память, должен выполнить функцию mmap () дважды; один раз, чтобы получить «золотой» виртуальный адрес, затем сопоставить блок с этим адресом, используя флаг MAP_FIXED.

Интересно, я работаю со встроенной системой с ядром 2.6. По умолчанию он будет предоставлять один и тот же виртуальный адрес всем вызовам mmap () для данного файлового дескриптора. Пойди разберись.

Боб Вирка

2 голосов
/ 23 июня 2011

Вы можете посмотреть на создание объекта совместно используемой памяти, используя shmget(), shmat() и т. Д. Сначала запустите процесс, который получает право инициализировать считанный в вашем файле объект совместно используемой памяти и скопировать его в адрес объекта совместно используемой памяти. пространство. Теперь любой другой процесс, который просто получает возвращаемое значение идентификатора совместно используемой памяти, может получить доступ к данным в пространстве совместно используемой памяти. Так, например, вы можете использовать схему инициализации типа, такую ​​как:

#include <sys/shm.h>

#define KEYVALUE 1000 //arbitrary value ... just needs to be shared between your processes

int file_size
//read your file and obtain its size in bytes;

//try to create the shared memory object
int shared_mem_id;
void* shared_mem_ptr = NULL;

if ((shared_mem_id = shmget(KEYVALUE, file_size, S_IRUSR | S_IWUSR IPC_CREAT | IPC_EXCL)) == -1)
{
    if (errno == EEXIST)
    {
        //shared memory segment was already created, so just get its ID value
        shared_mem_id = shmget(KEYVALUE, file_size, S_IRUSR | S_IWUSR);
        shared_mem_ptr = shmat(shared_mem_id, NULL, 0)
    }
    else
    {
        perror("Unable to create shared memory object");
        exit(1);
    }
}
else
{
    shared_mem_ptr = shmat(shared_mem_id, NULL, 0);

    //copy your file into shared memory via the shared_mem_ptr

}

//work with the shared data ...

Последний процесс, использующий объект совместно используемой памяти, непосредственно перед его уничтожением скопирует измененное содержимое из совместно используемой памяти обратно в фактический файл. Возможно, вы также захотите выделить структуру в начале вашего объекта общей памяти, которую можно использовать для синхронизации, т. Е. Будет некоторый тип «магического числа», которое будет установлен процессом инициализации, чтобы ваши другие процессы знали, что данные были правильно инициализированы в объекте общей памяти перед доступом к нему. В качестве альтернативы можно использовать именованный семафор или семафор System V, чтобы убедиться, что ни один процесс не пытается получить доступ к объекту общей памяти до его инициализации.

...