

- Главная
- Каталог
- Интернет технологии
- С/С++ Portal | Программирование
С/С++ Portal | Программирование
Присоединяйтесь к нашему каналу и погрузитесь в мир для C/C++-разработчика
Статистика канала
Полная статистикаchevron_rightвсё, с этим регионом памяти покончено.
int munmap(void *addr, size_t length);{}
Один вызов создаёт mapping, другой его разрушает. Прозрачно и логично.
Ниже минимальный пример на C, где показан полный цикл использования.
Обрати внимание что munmap() вызывается до close(). После вызова munmap доступ к mapped_memory приведёт к SIGSEGV.
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main() {
int fd = open("test.file", O_RDWR | O_CREAT, 0666);
ftruncate(fd, 4096); // убеждаемся, что размер файла кратен странице
// маппим файл в память
char *map = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
strcpy(map, "Hello from mapped memory!");
// явно освобождаем mapping
munmap(map, 4096);
// теперь закрываем дескриптор
close(fd);
return 0;
}{}
И важно то что, это не баг, а фича.
Разделение close() и munmap() даёт гибкость. Программа может закрыть файл для дальнейших операций ввода-вывода, но оставить его содержимое доступным через mapping с минимальными накладными расходами.
Такой подход лежит в основе многих системных механизмов:
загрузка и выгрузка динамических библиотек (.so), высокопроизводительный zero-copy I/O в серверах и базах данных, организация общей памяти между процессами.Если работаешь с низкоуровневым I/O, стоит держать это в голове.
Выделение памяти: получаем память через mmap с правами PROT_READ | PROT_WRITE Запись: JIT пишет в эту память свежесгенерированный машинный код, как в обычный буфер Защита: вызываем mprotect() и меняем права на PROT_READ | PROT_EXECПрава на запись убираются, и теперь код можно безопасно выполнить. При этом эта область памяти никогда не находится в состоянии RWX. Минимальный пример, который создает и запускает функцию во время выполнения: Этот код пишет одну инструкцию ret (0xc3) в буфер, делает память исполняемой с помощью mprotect и вызывает ее как функцию.
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
int main() {
// Выделяем одну страницу памяти
char *mem = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
// Копируем одну инструкцию "return"
memcpy(mem, "\xc3", 1);
// Делаем память исполняемой (и только для чтения)
mprotect(mem, 4096, PROT_READ | PROT_EXEC);
// Создаем указатель на функцию и вызываем "функцию"
void (*func)() = (void (*)())mem;
printf("Calling generated code...\n");
func();
printf("Returned successfully!\n");
return 0;
}{}
Но mprotect важен не только для JIT. Это один из фундаментальных механизмов безопасности современных систем.
Он обеспечивает Data Execution Prevention (W^X), гарантируя, что сегменты с данными нельзя выполнить как код. Это блокирует атаки через buffer overflow, где злоумышленник пытается вставить и исполнить свой код в данных.
Также через него создают guard-pages - области памяти с PROT_NONE рядом со стеками. Если стек переполняется и пересекает guard-page, программа сразу падает вместо того, чтобы тихо портить память или запускать чужой код.
Вот почему mprotect одновременно и инструмент для JIT-магии, и кирпич в фундаменте безопасности операционных систем.
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv) {
int fd = open(argv[1], O_RDONLY);
struct stat s;
fstat(fd, &s);
// Мапим весь файл в адресное пространство процесса
char *data = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (data != MAP_FAILED) {
// Теперь работаем с файлом как с огромным массивом!
printf("Первый символ: %c\n", data[0]);
printf("Символ посередине: %c\n", data[s.st_size / 2]);
}
munmap(data, s.st_size);
close(fd);
return 0;
}{}
Вся мощь mmap раскрывается через флаги. Два самых важных:
• MAP_PRIVATE — приватное копирование при записи. Изменения не пишутся обратно в файл и не видны другим процессам. Идеально, если нужно только читать.
• MAP_SHARED — изменения попадают обратно в файл и видны всем другим процессам, которые тоже мапят этот файл.
Этот механизм настолько базовый, что Linux использует его повсюду:
• так динамический линкер загружает .so библиотеки
• используется для быстрой разделяемой памяти между процессами
• лежит в основе баз данных и поисковых движков, которые работают с огромными объемами данных
mmap — один из ключевых механизмов современных ОС.
LINUXTG25»: открыть курс на Stepik
#include <unistd.h>
#include <fcntl.h>
int main() {
int fd = open("sparse.file", O_WRONLY | O_CREAT, 0644);
if (fd == -1) return 1;
// Seek 10GB forward
lseek(fd, 10000000000L, SEEK_SET);
// Write a single byte to mark the new end
write(fd, "", 1);
close(fd);
return 0;
}{}
Проверь через ls -lh и du -h.
Но как программы находят эти дырки? Читать файл тупо подряд медленно.
В современных Linux (начиная с 3.1) lseek прокачали двумя новыми флагами:
SEEK_HOLE: находит следующую дырку.
SEEK_DATA: находит следующий участок с реальными данными.
Это позволяет очень эффективно обрабатывать sparse файлы.
И это не просто трюк. Это основа производительности в таких вещах, как:
- инструменты бэкапа (пропускают пустые блоки и экономят место)
- образы дисков виртуальных машин (qcow2 и подобные)
- базы данных (выделяют большие файлы без реального расхода дискового пространства заранее)
lseek дает масштабируемость на ровном месте.
Отзывы канала
всего 2 отзыва
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
С/С++ Portal | Программирование — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 16.6K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 20.1, количество отзывов – 2, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 6293.7 ₽, а за 20 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий