Как читать и писать с помощью mmap () в системе Linux - PullRequest
4 голосов
/ 13 февраля 2012

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

Когда я только начинал, у меня были ошибки в сегментах, и если я не понял, ничего не произошло, поэтому я немного погуглил.Я нашел эту книгу http://www.advancedlinuxprogramming.com/alp-folder/alp-ch05-ipc.pdf, где на странице 107 есть некоторый полезный код.Я скопировал, вставил этот код, сделал некоторые небольшие изменения и получил этот код:

int fd;
void* file_memory;

/* Prepare a file large enough to hold an unsigned integer.  */
fd = open ("mapTester", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

//Make the file big enough
lseek (fd, 4 * 10 + 1, SEEK_SET);
write (fd, "", 1);
lseek (fd, 0, SEEK_SET);

/* Create the memory mapping.  */
file_memory = mmap (0, 4 * 10, PROT_WRITE, MAP_SHARED, fd, 0);
close (fd);

/* Write a random integer to memory-mapped area.  */
sprintf((char*) file_memory, "%d\n", 22);

/* Release the memory (unnecessary because the program exits).  */
munmap (file_memory, 4 * 10);

cout << "Mark" << endl;

//Start the part where I read from the file

int integer;

/* Open the file.  */
fd = open (argv[1], O_RDWR, S_IRUSR | S_IWUSR);

/* Create the memory mapping.  */
file_memory = mmap (0, 4 * 10, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
close (fd);

/* Read the integer, print it out, and double it.  */
scanf ((char *) file_memory, "%d", &integer);
printf ("value: %d\n", integer);
sprintf ((char*) file_memory, "%d\n", 2 * integer);

/* Release the memory (unnecessary because the program exits).  */
munmap (file_memory, 4 * 10);

Но я получаю ошибки сегмента после метки "mark".

Затем я заменяю «часть чтения» следующим:

fd = open("mapTester", O_RDONLY);

int* buffer = (int*) malloc (4*10);

read(fd, buffer, 4 * 10);

for(int i = 0; i < 1; i++)
{
    cout << buffer[i] << endl;
}

Это некоторый рабочий код, который показывает мне, что файл пуст.Я пробую пару способов записи в отображение без каких-либо изменений в результате.

Так как же я могу написать свой код?И мой код чтения mmap кажется нормальным (на всякий случай, если вы видите некоторые очевидные недостатки)?

Я нашел некоторые другие ресурсы, которые мне еще не помогли, но, поскольку я новый пользователь, я могу публиковать не более 2 ссылок.

Ответы [ 2 ]

4 голосов
/ 13 февраля 2012

Вы должны проверить результат mmap .Если это дает MAP_FAILED, проверьте errno , чтобы выяснить, почему.

И вам лучше будет отобразить несколько страниц, часто по 4 Кбайт каждая, и будет дано sysconf (_SC_PAGESIZE)

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

Вы можете использовать straceв существующих программах Linux, чтобы узнать, какие системные вызовы они выполняют.

См. также this о /proc/ и т. д.

1 голос
/ 14 февраля 2012

Ваш scanf() вызов должен быть sscanf(), а при втором открытии следует использовать "mapTester" вместо argv[1] в качестве имени файла.Когда я исправляю эти ошибки, ваша опубликованная программа работает (распечатывает 22 и оставляет 44 в файле).

...