Я пытаюсь сделать класс файла журнала, процесс, который я хочу, чтобы выполнить следующие действия:Не очень понятно, почему mmap не делает то, что я думаю, что он должен. C++ Linux
- Открыть файл (или создать)
- Карты файла в памяти
- Закрыть де файл
- Запись в память
файл будет иметь размер 1024Кб (постоянной SIZE_KB).
До сих пор это то, что я делаю:
Im создание файла с правами на чтение и запись для владельца (S_IRUSR | S_IWUSR) и разрешения на чтение для отдыха (S_IRGRP | S_IROTH).
// Open the file. If the file doesnt exists it will create it
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int fd = open(path.c_str(), O_CREAT | O_RDWR, mode);
После этого я проверяю, если fd
является -1
:
if (fd < 0)
throw std::system_error(errno, std::system_category(), "couldnt open history");
#ifdef _DEBUG_
std::clog << "History with file descriptor " << fd << " opened" << std::endl;
#endif
Теперь я карту файл, но сначала мне нужно установить переменную длину с размером файла, который должен быть Mutiple из sysconf(_SC_PAGE_SIZE)
:
size_t length = (int)ceil(SIZE_KB*1024.0/sysconf(_SC_PAGE_SIZE))*sysconf(_SC_PAGE_SIZE);
/* ceil(size/page_size)*page_size*/
#ifdef _DEBUG_
std::clog << "Length is " << length << " bytes" << std::endl;
#endif
Mapping, block_start
частный указатель символ:
block_start = (char*)mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- Дополнительный вопрос: M_SHARED варианта сделать эту часть памяти, доступной для других процессов (?). Почему он также используется для того, чтобы СО сохранить изменения, внесенные в виртуальную память, в фактический файл?.
Проверка на наличие ошибок:
#ifdef _DEBUG_
std::clog << Returned: " << (int*)block_start << std::endl;
#endif
if (block_start == MAP_FAILED)
throw std::system_error(errno, std::system_category(), "couldnt map memory");
#ifdef _DEBUG_
std::clog << "History memory mapped" << std::endl;
#endif
И закрыть файл:
int result = close(fd);
if (result < 0)
throw std::system_error(errno, std::system_category(), "error closing history");
#ifdef _DEBUG_
std::clog << "History with file descriptor " << fd << " closed" << std::endl;
#endif
Теперь, я должен быть в состоянии добавить информацию в отображенной памяти, так что я пытался делать:
std::cout << "Attemping to write on first" << std::endl;
*block_start = 'A';
std::cout << "End" << std::endl;
(Внутри конструктора)
Это выход у меня есть:
History with file descriptor 3 opened
Length is 1048576 bytes
Returned: 0x7f7e9160a000
History memory mapped
History with file descriptor 3 closed
Attemping to write on first
Bus error (core dumped)
Я думаю, что это, возможно, придется делать с размером файла, так как созданный файл имеет 0 размер, но Im говоря ММАП сопоставить размер SIZE_KB*1024
байт, так почему это не работает?
-rw-r--r-- 1 dark dark 0 Dec 13 16:15 /home/dark/talk.log
Последнее предложение немного неправильно. Вы можете «mmap» сегмент * меньше * чем размер файла. –
Спасибо, что решил проблему, я думал, что это не нужно. Любой ответ на вопрос M_SHARED? – Ediolot
Потому что это то же самое. Потому что единственный способ для других процессов совместно использовать один и тот же сегмент памяти - это для mmap того же файла. Следовательно, вы должны иметь флаг MAP_SHARED, также обновляющий содержимое базового файла. В противном случае другие процессы не будут видеть изменения в файл mmapped, созданный вашим процессом. –