Проблемы с mmap сложных типов

У меня возникла проблема с доступом к общей памяти с помощью mmap для сложных типов.

Итак, я выделяю свою память в своем родительском процессе:

/* Create mmap file */
fid = open(TMP_FILE_NAME, O_RDWR | O_CREAT | O_EXCL, (mode_t) 0755);
if (fid < 0)
{
  printf("Bad Open of mmap file <%s>\n", TMP_FILE_NAME);
  die(-1);
}

/* Make mmap file Buffer Size */
status = ftruncate(fid, INPUT_BUFFER_SIZE); 
if (status)
{
    printf("Failed to ftruncate the file <%s>, status = %d\n", TMP_FILE_NAME, status);
    die(-1);
}

/* Initialize Shared Memory */
mmap_ptr = mmap((caddr_t) 0,
      INPUT_BUFFER_SIZE,        // Default Buffer Size
      PROT_WRITE | PROT_READ,   // R/W Permissions
      MAP_SHARED, // No file backing
      fid,  
      (off_t) 0);
if (mmap_ptr == MAP_FAILED)
{
    printf("Failed to perform mmap, Exiting\n");
    die(-1);
}

Теперь структура, которую я передаю в память своему дочернему процессу, выглядит следующим образом:

/* Data structue for IPC */
typedef struct {
    int current_active_id;
    int consume_remaining;
    Queue buffer;
} input_buffer;

где Queue — класс структуры данных из следующего: http://www.idevelopment.info/data/Programming/data_structures/c/Queue/Queue.shtml

В моем дочернем процессе все в порядке, когда я это делаю, он возвращает правильное значение:

printf("Got here... Shared Mem: %d\n", input_queue->consume_remaining);

но когда я делаю что-то вроде:

IsEmpty(input_queue->buffer)

он падает, и в коде очереди он делает только это:

return Q->Size == 0;

Любая помощь будет оценена по достоинству, спасибо!!


person J Kao    schedule 02.10.2011    source источник
comment
input_queue-›buffer не является допустимым адресом памяти в дочернем процессе. Как у вас дела с IPC? Вам нужно mmap тот же «общий» файл в дочернем процессе для выполнения IPC.   -  person Finslicer    schedule 02.10.2011
comment
В основном я запускаю дочерний процесс и создаю еще один mmap_ptr и привожу его к типу input_queue. Это прекрасно работает для базовых типов int, но не для указателя на очередь. Как мне выделить структуру данных очереди, чтобы она стала частью общей памяти?   -  person J Kao    schedule 02.10.2011


Ответы (2)


Queue является указателем на struct QueueRecord и должен быть выделен как таковой, предположительно с использованием того же сегмента разделяемой памяти. обратите внимание, что это также должно быть сопоставлено по одному и тому же адресу как в родительском, так и в дочернем, иначе вы не сможете разыменовать его.

person Hasturkun    schedule 02.10.2011
comment
Хорошо, я вижу, что это имеет смысл. Итак, в idevelopment.info/data/Programming/data_structures/c/ Queue/ вместо malloc я бы сделал mmap? - person J Kao; 02.10.2011
comment
Или, чтобы быть более ясным, как бы я мог разместить его в той же адресной области, что и структура, которую я mmap'ировал? - person J Kao; 02.10.2011
comment
@JKao: Вы можете изменить код, чтобы ваша отображаемая область содержала struct QueueRecord, который можно изменить, чтобы иметь гибкий элемент для использования в качестве массива вместо использования выделенного указателя. обратите внимание, однако, что текущая реализация скрывает определение структуры. - person Hasturkun; 02.10.2011

Структура, которую вы помещаете на карту, содержит указатели. Все указатели относятся к адресному пространству создавшего их процесса.

Если другой процесс не выполняет mmap по тому же адресу или делает это, но выделения, сделанные для очереди, не берутся из этого буфера, указатели в другом процессе будут недействительными.

person Mat    schedule 02.10.2011