сопоставить размер общей памяти, используя mmap, больше, чем установленный размер, сделанный ftruncate - PullRequest
0 голосов
/ 01 марта 2019

У меня есть несколько вопросов, основанных на приведенном ниже источнике:

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>

int g;
int main(void) {
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int)); // set size by sizeof(int)
    int *p1 = mmap(NULL, 10*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0); //now map  10*sizeof(int).
    if (p1== MAP_FAILED) {
        printf("*****************error");
    }
    *p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
    if (p1== MAP_FAILED) {
        printf("*****************error");
    }

    *p1=89;

    return g;
}

Вопрос 1: почему я не вижу ошибок, когда я устанавливаю размер как size_of (int), а затем отображаю 10 * size_of (int)

Вопрос 2: сколько созданных общих папок создано здесь?я имею в виду, есть только один общий мем или два, как я сделал mmap дважды?

Спасибо

1 Ответ

0 голосов
/ 01 марта 2019

Учитывая код

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>

int g;
int main(void) {
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int)); // set size by sizeof(int)
    int *p1 = mmap(NULL, 10*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0); //now map  10*sizeof(int).
    *p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
    if (!p1){
        printf("*****************error");
    }
    *p1 = g;
    *p1=89;

    return g;
}

Вопрос 1: почему я не вижу никакой ошибки, когда я устанавливаю размер как size_of (int) и затем отображаю 10 * size_of (int)

Поскольку вы не проверяете возвращаемое значение из mmap(), вы не знаете, произошла ошибка или нет.При немедленном повторном вызове mmap() с

*p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);

вы маскируете любые потенциальные ошибки при первом вызове mmap() и также теряете всю память, которая была успешно распределена.

Вопрос 2: сколько инстансов общих мемов создано здесь?я имею в виду, есть только один общий мем, созданный или два, как я сделал mmap дважды?

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

Если первый вызов был успешным, вы вытекли из памяти.

Обратите внимание, что если вы пытались записать в mmap()Если размер сегмента, который вы установили с помощью ftruncate(), будет превышать конечный размер, файл не будет расти.Согласно документации POSIX mmap() :

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

В Linux попытка получить доступ к данным mmap() за концом сопоставленного файла, вероятно, приведет к вашему процессу получение SIGBUS сигнала .

...