2013-02-22 3 views
2

Я пытаюсь настроить сегмент разделяемой памяти для хранения массива строк. В качестве примера этот массивLinux shmget() function in C++

пример строки [] = {«Это», «Пример», «строк»};

Затем я пытаюсь вызвать shmget, чтобы получить резервную сумму общей памяти os.

shmget (IPC_PRIVATE, SizeOf (пример), IPC_CREAT); // Я надеюсь, что это создает сегмент разделяемой памяти

Я нашел эту site, который говорит: «Ключевой аргумент является значением доступа, связанное с идентификатор семафора «Какой идентификатор семафора и как его создать.

Это компилируется с использованием g ++ -Wall, но я не знаю, как проверить и посмотреть, есть ли у него. Согласно руководству shm в linux, где IPC_PRIVATE я должен указать что-то типа «key_t». Мои мысли - это ключ к тому, как я идентифицирую общую память, то есть укажите строку как имя разделяемой памяти и/или номер идентификатора.

Чтение руководства через указывает, что shmget() возвращает «shmid». Опять же, что такое shmid, это int, string, указатель или какой-то особый тип, и так ли это, как я идентифицирую сегмент разделяемой памяти? Кроме того, если shmget() возвращает что-то, мне не нужно назначать его чему-то?

Если вы можете порекомендовать учебник или обзор, я был бы очень признателен. В дополнение к конкретным вопросам выше я хотел бы получить пример доступа к общей памяти из потока, который будет создан из команды fork().

Моя конечная цель - порождать поток для каждой строки в моем массиве, который будет выполнять своего рода инверсию. Это всего лишь небольшая небольшая задача, чтобы начать работу с разделяемой памятью и pthreads, так как я не нашел учебника для работы.

+0

'shmget()' возвращает 'int' (http://www.kernel.org/doc/man-pages/online/pages/man2/shmget.2.html). Таким образом, 'shmid' будет целым числом. –

ответ

1

Хорошо, прежде чем я объясню все второстепенные детали, очень важно, что при совместном использовании данных через общую память вы понимаете, что вы действительно вкладываете в общую память.

В вашем примере, у вас есть:

string example[] = {"This is", "An Example ", "of strings"}; 

Вы, наверное, не думал очень трудно об этом, но как вы думаете, acutal строка хранится внутри «станд :: строка»? Я не знаю точных данных в этом конкретном случае, но одна довольно типичная реализация будет примерно такой [это упрощено, настоящая «строка класса» - это объявление класса шаблона с использованием класса basic_string в качестве основы].

class string 
{ 
    char *str; 
    int len; 
} 

Итак, если вы копируете example в общую память, то вы будете иметь в вашей общей памяти, три указателя и три целых числа. Эти указатели указывают на некоторую память, которая почти наверняка НЕ ​​входит в общую память ... Очевидно, что этот адрес памяти в «другом процессе» не будет тем, что вы ожидаете [ну, по крайней мере, если строки не постоянны, а ваш процесс разворачивается до того, как строки были созданы, но если строки являются постоянными и/или уже там, когда вилка происходит, вам действительно не нужна разделяемая память, верно?]

Типичным решением для этого является ТОЛЬКО хранить данные в общей памяти, которые являются «обычными старыми данными» (поэтому нет объектов, которые имеют функции-члены или указатели внутри них). Один из способов добиться этого - «сериализовать» данные - это то же самое, что вы сделали бы, если бы захотели хранить данные в файле.

Это компилируется с использованием g ++ -Wall, но я не знаю, как проверить и посмотреть, есть ли у него . Согласно руководству shm в linux, где IPC_PRIVATE - это , следует указать что-то типа «key_t». Мои мысли - это ключ , как я идентифицирую общую память, т. Е. Укажу строку как имя общей памяти или и для идентификационного номера.

Вы можете либо указать ключ или использовать IPC_PRIVATE (который в человеко-странице объясняется как «неудачным названием», и что «IPC_NEW» было бы лучше coice)

Чтение вручную, указывает, что shmget() возвращает «shmid». Опять же, что это shmid, это int, string, pointer или это какого-то особого типа, и это то, как я идентифицирую свой общий сегмент памяти ? Также если shmget() возвращает что-то, мне не понадобится , чтобы присвоить его чему-нибудь?

Сайт вы ссылаетесь на самом деле объясняет, как хранить shmid:

int shmid; 

... Several lines of code... 

if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) { 

Я думаю, что это должно быть достаточно, чтобы вы начали.

+0

Не знаю наверняка, потому что я не тестировал, но думаю, что можно будет использовать класс std :: string с пользовательским распределителем и/или новым местом размещения, которые помещают его в область shm ... Как вы думаете возможно? – Filipe

+0

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