Как ядро ​​Linux назначает указатели памяти, когда процесс использует shm_open ()? - PullRequest
1 голос
/ 23 февраля 2011

Я в Linux 2.6, и у меня странная проблема. У меня есть 3 параллельных процесса (разветвленных из одного процесса), которые должны получить 3 РАЗЛИЧНЫХ сегмента общей памяти, по одному для каждого процесса. Каждый процесс выполняет этот код (обратите внимание, что тип «сообщения» определяется пользователем)

    message *m;
    int fd = shm_open("message", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
    ftruncate(fd, sizeof(message));
    m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    char messagename[16];
    snprintf(messagename, sizeof(messagename), "%p", m);
    char path[32] = "/dev/shm/";
    strcat(path, messagename);
    rename("/dev/shm/message", path);

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

Однако при выполнении программы я попытался напечатать (для целей отладки) указатели, которые каждый процесс получил при отображении fd, полученного с помощью shm_open, и я заметил, что все они получили один и тот же указатель. Как это возможно? Я подумал, что, возможно, другие процессы сделали shm_open () после первого и до того, как он переименовал сегмент, поэтому я также попытался сделать эти строки кода атомарной операцией, используя общий мьютекс процесса, но проблема сохраняется.

Я был бы очень признателен за любую помощь или предложение.

Ответы [ 3 ]

2 голосов
/ 23 февраля 2011

Все ваши процессы начинались с одинакового расположения адресного пространства в момент разветвления, а затем следовали очень похожим путям кода.Поэтому неудивительно, что все они имеют одинаковое значение m.

Однако, когда они стали отдельными процессами, их адресные пространства стали независимыми, поэтому они имеют одинаковое значение .из m не означает, что все m указывают на одну и ту же вещь.

Более того, я не уверен, что ваша идея переименовать запись /dev/shm после создания блока общей памятиявляется безопасным или портативнымЕсли вы хотите, чтобы блок общей памяти каждого процесса имел уникальное имя, почему бы не основывать имя на идентификаторе процесса (который гарантированно будет уникальным в данный момент времени) и передавать его непосредственно в shm_open, а не в беспокойство?переименовать его потом?

1 голос
/ 23 февраля 2011

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

0 голосов
/ 23 февраля 2011

Я решил похожую проблему, просто сделав mmap перед разветвлением.Поэтому после разветвления одна и та же область распределяется между всеми процессами.Затем я помещаю свои семафоры и мьютексы в определенные позиции.Работает отлично.

...