File mapping c linux
void * mmap(void * start , size_t length , int prot , int flags , int fd , off_t offset );
int munmap(void * start , size_t length );
ОПИСАНИЕ
Аргумент prot описывает желаемый режим защиты памяти (он не должен конфликтовать с режимом открытия файла). Оно является либо PROT_NONE либо побитовым ИЛИ одного или нескольких флагов PROT_*. PROT_EXEC (данные в страницах могут исполняться); PROT_READ (данные можно читать); PROT_WRITE (в эту область можно записывать информацию); PROT_NONE (доступ к этой области памяти запрещен).
Параметр flags задает тип отражаемого объекта, опции отражения и указывает, принадлежат ли отраженные данные только этому процессу или их могут читать другие. Он состоит из комбинации следующих битов: MAP_FIXED Не использовать другой адрес, если адрес задан в параметрах функции. Если заданный адрес не может быть использован, то функция mmap вернет сообщение об ошибке. Если используется MAP_FIXED, то start должен быть пропорционален размеру страницы. Использование этой опции не рекомендуется. MAP_SHARED Разделить использование этого отражения с другими процессами, отражающими тот же объект. Запись информации в эту область памяти будет эквивалентна записи в файл. Файл может не обновляться до вызова функций msync (2) или munmap (2) . MAP_PRIVATE Создать неразделяемое отражение с механизмом copy-on-write. Запись в эту область памяти не влияет на файл. Не определено, являются или нет изменения в файле после вызова mmap видимыми в отраженном диапазоне.
Вы должны задать либо MAP_SHARED, либо MAP_PRIVATE.
Эти три флага описаны в POSIX.1b (бывшем POSIX.4) and SUSv2. В Linux также анализируются следующие нестандартные флаги: MAP_DENYWRITE Этот флаг игнорируется. (Раньше он обозначал, что попытки записи в подчиненные файлы должны завершаться с кодом ошибки ETXTBUSY. Но это стало основой для атак типа ‘отказ-в-доступе’ — ‘denial-of-service’.) MAP_EXECUTABLE Этот флаг игнорируется. MAP_NORESERVE (Используется вместе с MAP_PRIVATE.) Не выделяет страницы пространства подкачки для этого отображения. Если пространство подкачки выделяется, то это частное пространство копирования-при-записи может быть изменено. Если оно не выделено, то можно получить SIGSEGV при записи и отсутствии доступной памяти. MAP_LOCKED (Linux 2.5.37 и выше) Блокировать страницу или размеченную область в памяти так, как это делает mlock() . Этот флаг игнорируется в старых ядрах. MAP_GROWSDOWN Используется для стеков. Для VM системы ядра обозначает, что отображение должно распространяться вниз по памяти. MAP_ANONYMOUS Отображение не резервируется ни в каком файле; аргументы fd и offset игнорируются. Этот флаг вместе с MAP_SHARED реализован с Linux 2.4. MAP_ANON Псевдоним для MAP_ANONYMOUS. Не используется. MAP_FILE Флаг совместимости. Игнорируется.
MAP_32BIT Поместить размещение в первые 2Гб адресного рпостранства процесса. Игнорируется, если указано MAP_FIXED . Этот флаг сейчас поддерживается только на x86-64 для 64-битных программ.
Некоторые системы документируют дополнительные флаги MAP_AUTOGROW, MAP_AUTORESRV, MAP_COPY и MAP_LOCAL.
fd должно быть корректным описателем файла, если только не установлено MAP_ANONYMOUS, так как в этом случае аргумент игнорируется.
offset должен быть пропорционален размеру страницы, получаемому при помощи функции getpagesize (2).
Memory mapped by mmap is preserved across fork (2), with the same attributes.
A file is mapped in multiples of the page size. For a file that is not a multiple of the page size, the remaining memory is zeroed when mapped, and writes to that region are not written out to the file. The effect of changing the size of the underlying file of a mapping on the pages that correspond to added or removed regions of the file is unspecified. Системный вызов munmap удаляет все отражения из заданной области памяти, после чего все ссылки на данную область будут вызывать ошибку «неправильное обращение к памяти» (invalid memory reference). Отражение удаляется автоматически при завершении процесса. С другой стороны, закрытие файла не приведет к снятию отражения.
Адрес start должно быть кратен размеру страницы. Все страницы, содержащие часть указанного диапазона, не отображены, и последующие ссылки на эти страницы будут генерировать SIGSEGV. Это не будет являться ошибкой, если указанный диапазон не содержит отображенных страниц. Для отображений ‘файл-бэкэнд’ поле st_atime отображаемого файла может быть обновлено в любой момент между mmap() и соответствующим снятием отображения; первое обращение к отображенной странице обновит поле, если оно до этого уже не было обновлено.
Поля st_ctime и st_mtime файла, отображенного по PROT_WRITE и MAP_SHARED, будут обновлены после записи в отображенний диапазон, и до вызова последующего msync() с флагом MS_SYNC или MS_ASYNC, если такой случится.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
ЗАМЕЧАНИЯ
НАЙДЕННЫЕ ОШИБКИ
Использование отражаемой области памяти может привести к следующим сигналам: SIGSEGV (попытка записи в область памяти, заданную mmap как область для чтения); SIGBUS (попытка доступа к части буфера, которая не является файлом; например, она может находиться за пределами файла. Подобной является ситуация, когда другой процесс уменьшает длину файла).
Источник
пФПВТБЦБЕНБС РБНСФШ
пФПВТБЦБЕНБС РБНСФШ РПЪЧПМСЕФ ТБЪМЙЮОЩН РТПГЕУУБН ПВЭБФШУС ЮЕТЕЪ ПВЭЕДПУФХРОЩК ЖБКМ. пФПВТБЦБЕНБС РБНСФШ НПЦЕФ ЙУРПМШЪПЧБФШУС ДМС ЧЪБЙНПДЕКУФЧЙС РТПГЕУУПЧ ЙМЙ ЛБЛ РТПУФПК УРПУПВ ДМС ПВТБЭЕОЙС Л УПДЕТЦЙНПНХ ЖБКМБ. пФПВТБЦБЕНБС РБНСФШ ЖПТНЙТХЕФ БУУПГЙБГЙА НЕЦДХ ЖБКМПН Й РБНСФША РТПГЕУУБ. Linux ТБЪВЙЧБЕФ ЖБКМ ОБ ЛХУЛЙ ТБЪНЕТПН УФТБОЙГЩ Й ЪБФЕН ЛПРЙТХЕФ ЙИ Ч УФТБОЙГЩ ЧЙТФХБМШОПК РБНСФЙ ФБЛ, ЮФПВЩ ПОЙ НПЗМЙ ВЩФШ РТЕДУФБЧМЕОЩ Ч БДТЕУОПН РТПУФТБОУФЧЕ РТПГЕУУБ. фБЛЙН ПВТБЪПН, РТПГЕУУ НПЦЕФ ЮЙФБФШ УПДЕТЦБОЙЕ ЖБКМБ ПВЩЮОЩН ДПУФХРПН Л РБНСФЙ. пО НПЦЕФ ФБЛЦЕ ЙЪНЕОЙФШ УПДЕТЦЙНПЕ ЖБКМБ, ЪБРЙУЩЧБС Ч РБНСФШ. юФП РПЪЧПМСЕФ ВЩУФТП ЧЪБЙНПДЕКУФЧПЧБФШ У ЖБКМПН.
уХЭЕУФЧХАФ ЙОЩЕ НЕФПДЩ ЙУРПМШЪПЧБОЙС ПФПВТБЦБЕНПК РБНСФЙ. оЕЛПФПТЩЕ ЙЪ ОЙИ ПРЙУБОЩ Ч ТБЪДЕМЕ «дТХЗЙЕ НЕФПДЩ ЙУРПМШЪПЧБОЙС ДМС mmap.»
пФПВТБЦЕОЙЕ ПВЩЮОПЗП ЖБКМБ
юФПВЩ ПФПВТБЪЙФШ ПВЩЮОЩК ЖБКМ Ч РБНСФШ РТПГЕУУБ ЙУРПМШЪХКФЕ ЧЩЪПЧ mmap ( Memory MAPped , РТПЙЪОПУЙНПЕ «em-map»). рЕТЧЩК РБТБНЕФТ — БДТЕУ, ОБЮЙОБС У ЛПФПТПЗП чЩ ИПФЕМЙ ВЩ, ЮФПВЩ Linux ПФПВТБЪЙМ ЖБКМ; ЪОБЮЕОЙЕ NULL ЪБУФБЧМСЕФ Linux ЧЩВЙТБФШ РЕТЧЩК ДПУФХРОЩК БДТЕУ. чФПТПК РБТБНЕФТ — ДМЙОБ ПФПВТБЦЕОЙС Ч ВБКФБИ. фТЕФЙК РБТБНЕФТ ПРТЕДЕМСЕФ ЪБЭЙФХ ДМС ПФПВТБЦБЕНПЗП БДТЕУОПЗП ЙОФЕТЧБМБ. ъБЭЙФБ УПУФПЙФ ЙЪ РПТБЪТСДОПЗП «ЙМЙ» ЙЪ PROT_READ , PROT_WRITE , Й PROT_EXEC , ЮФП УППФЧЕФУФЧХЕФ ЮФЕОЙА, ЪБРЙУЙ, Й ТБЪТЕЫЕОЙА ОБ ЧЩРПМОЕОЙЕ. юЕФЧЕТФЩК РБТБНЕФТ — ЪОБЮЕОЙЕ ЖМБЦЛБ, ПРТЕДЕМСАЭЕЕ ДПРПМОЙФЕМШОЩЕ ПРГЙЙ. рСФЩК РБТБНЕФТ — ДЕУЛТЙРФПТ ПФЛТЩФПЗП ЖБКМБ, ЛПФПТЩК ВХДЕФ ПФПВТБЦЕО. рПУМЕДОЙК РБТБНЕФТ — УНЕЭЕОЙЕ ПФ ОБЮБМБ ЖБКМБ, У ЛПФПТПЗП ОБЮОЕФУС ПФПВТБЦЕОЙЕ. чЩ НПЦЕФЕ ПФПВТБЪЙФШ ЧЕУШ ЙМЙ ЮБУФШ ЖБКМБ Ч РБНСФШ, ЧЩВЙТБС ОБЮБМШОПЕ УНЕЭЕОЙЕ Й ДМЙОХ.
ъОБЮЕОЙЕ ЖМБЦЛБ — РПТБЪТСДОПЕ «ЙМЙ» ЬФЙИ ПЗТБОЙЮЕОЙК:
- MAP_FIXED — ПФПВТБЦБФШ ФПМШЛП ОБЮЙОБС У ХЛБЪБОПЗП БДТЕУБ, ЕУМЙ ОЕ ХДБУФУС — ЧЕТОХФШ ПЫЙВЛХ, Б ОЕ ЙУЛБФШ РПДИПДСЭЙК. ьФПФ БДТЕУ ДПМЦЕО ВЩФШ ЧЩТПЧОЕО ОБ ЗТБОЙГХ УФТБОЙГЩ.
- MAP_PRIVATE — РТПЙЪЧПДЙФШ ЪБРЙУШ ЙЪНЕОЕОЙК ОЕ Ч ПФПВТБЦЕООЩК ЖБКМ, Б Ч ЕЗП ЛПРЙА. оЙЛБЛПК ДТХЗПК РТПГЕУУ ОЕ ХЧЙДЙФ, ЙЪНЕОЕОЙК Ч ЖБКМЕ. ьФПФ ТЕЦЙН ОЕ НПЦЕФ ЙУРПМШЪПЧБФШУС У MAP_SHARED .
- MAP_SHARED — ЙЪНЕОЕОЙС Ч РБНСФЙ ОЕНЕДМЕООП ПФТБЦБАФУС Ч ПУОПЧОПН ЖБКМЕ ЧНЕУФП ВХЖЕТЙЪБГЙЙ. йУРПМШЪХКФЕ ЬФПФ ТЕЦЙН ДМС НЕЦРТПГЕУУПЧПЗП ЧЪБЙПДЕКУФЧЙС. оЕ ДПМЦОП ВЩФШ ЙУРПМШЪПЧБООП ЧНЕУФЕ У MAP_PRIVATE .
хУРЕЫОЩК ЧЩЪПЧ ЧПЪЧТБЭБЕФ ХЛБЪБФЕМШ ОБ ОБЮБМП РБНСФЙ. рТЙ ПЫЙВЛЕ, ЧПЪЧТБЭБЕФ MAP_FAILED . лПЗДБ ЧЩ ЪБЛПОЮЙМЙ ТБВПФХ У ХРТБЧМЕОЙЕН РБНСФША, ПУЧПВПДЙФЕ ЕЕ РТЙ РПНПЭЙ munmap . рЕТЕДБКФЕ БДТЕУ ОБЮБМБ Й ДМЙОХ ПВМБУФЙ ПФПВТБЦБЕНПК РБНСФЙ. Linux БЧФПНБФЙЮЕУЛЙ ПУЧПВПЦДБЕФ ПФПВТБЦБЕНХА РБНСФШ РТЙ ЪБЧЕТЫЕОЙЙ РТПГЕУУБ.
рТЙНЕТ РТПЗТБННЩ
дБЧБКФЕ РПУНПФТЙН ОБ ДЧЕ РТПЗТБННЩ ДЕНПОУФТЙТХАЭЙЕ ЙУРПМШЪПЧБОЙЕ ПВМБУФЙ ПФПВТБЦБЕНПК РБНСФЙ, У ГЕМША ЮФЕОЙС Й ЪБРЙУЙ Ч ЖБКМБН. рЕТЧБС РТПЗТБННБ, МЙУФЙОЗ 5.5, ЗЕОЕТЙТХЕФ УМХЮБКОПЕ ЮЙУМП Й РЙЫЕФ ЕЗП Ч ЖБКМ. чФПТБС РТПЗТБННБ, МЙУФЙОЗ 5.6, ЮЙФБЕФ ЮЙУМП, РЕЮБФБЕФ ЕЗП, Й ХДЧБЙЧБЕФ ЕЗП Ч ЖБКМЕ. пВЕ РТПЗТБННЩ УЮЙФЩЧБАФ ЙНЕОБ ПФПВТБЦБЕНЩИ ЖБКМПЧ ЙЪ ЛПНБОДОПК УФТПЛЙ.
Listing 5.5 (mmap-write.c) ъБРЙУЩЧБЕФ УМХЮБКОПЕ ЮЙУМП Ч ПФПВТБЦБЕНХА РБНСФШ
рТПЗТБННБ mmap-write ПФЛТЩЧБЕФ ЖБКМ, УПЪДБЧБС ЕЗП, ЕУМЙ ПО РТЕЦДЕ ОЕ УХЭЕУФЧПЧБМ. фТЕФЙК РБТБНЕФТ ХЛБЪЩЧБЕФ ТЕЦЙН ДПУФХРБ ДМС ЮФЕОЙС Й ЪБРЙУЙ. рПУЛПМШЛХ НЩ ОЕ ЪОБЕН ДМЙОХ ЖБКМБ, НЩ ЙУРПМШЪХЕН lseek , ЮФПВЩ ЗБТБОФЙТПЧБФШ, ЮФП ЖБКМ СЧМСЕФУС ДПУФБФПЮОП ВПМШЫЙН, ЮФПВЩ УПИТБОЙФШ ГЕМПЕ ЮЙУМП . рПУМЕ ЮЕЗП ЧПЪЧТБЭБЕНУС Л ОБЮБМХ ЖБКМБ.
рТПЗТБННБ ПФПВТБЦБЕФ ЖБКМ Й ЪБФЕН ЪБЛТЩЧБЕФ ДЕУЛТЙРФПТ ЖБКМБ, РПФПНХ ЮФП ПО ВПМШЫЕ ОЕ ОХЦЕО. рТПЗТБННБ РЙЫЕФ УМХЮБКОПЕ ГЕМПЕ ЮЙУМП Ч ПФПВТБЦБЕНХА РБНСФШ, ФБЛЙН ПВТБЪПНЙ Ч ЖБКМ, Й ПУЧПВПЦДБЕФ ПФПВТБЦБЕНХА РБНСФШ. чЩЪПЧ munmap ОЕОХЦЕО, РПФПНХ ЮФП Linux БЧФПНБФЙЮЕУЛЙ ПУЧПВПДЙМ ВЩ ПФПВТБЦБЕНХА РБНСФШ Й ЖБКМ, ЛПЗДБ РТПЗТБННБ ЪБЧЕТЫЙФУС.
Listing 5.6 (mmap-read.c) юЙФБЕФ ЮЙУМП ЙЪ ЖБКМБ ПФПВТБЦЕООПЗП Ч РБНСФЙ Й ХДЧБЙЧБЕФ ЮЙУМП.
рТПЗТБННБ mmap-read ЮЙФБЕФ ЮЙУМП ЙЪ ЖБКМБ Й ЪБФЕН ЪБРЙУЩЧБЕФ ЕЗП ХДЧПЕООПЕ ЪОБЮЕОЙЕ Ч ЖБКМХ. пФЛТЩЧБЕФ ЖБКМ Й ПФПВТБЦБЕФ ДМС ФПЗП, ЮФПВЩ ЮЙФБФШ Й РЙУБФШ Ч ОЕЗП. рПУЛПМШЛХ НЩ НПЦЕН РТЕДРПМПЦЙФШ, ЮФП ЖБКМ СЧМСЕФУС ДПУФБФПЮОП ВПМШЫЙН, ЮФПВЩ УПИТБОЙФШ ГЕМПЕ ЮЙУМП ВЕЪ ЪОБЛБ, НЩ ОЕ ДПМЦОЩ ЙУРПМШЪПЧБФШ lseek , ЛБЛ Ч РТЕДЩДХЭЕК РТПЗТБННЕ. рТПЗТБННБ ЮЙФБЕФ Й БОБМЙЪЙТХЕФ ЪОБЮЕОЙЕ ЙУРПМШЪХС scanf Й ЪБФЕН ЖПТНБФЙТХЕФ Й ЪБРЙУЩЧБЕФ ХДЧПЕООПЕ ЪОБЮЕОЙЕ, ЙУРПМШЪХС sprintf . чПФ РТЙНЕТ ЪБРХУЛБ РТЙНЕТПЧ РТПЗТБНН. ъДЕУШ ПФПВТБЦБЕН ЖБКМ /tmp/integer-file .
ъБНЕФШФЕ, ЮФП ФЕЛУФ 42 ВЩМ ЪБРЙУБО Ч ЖБКМ ОБ ДЙУЛЕ ВЕЪ ЧЩЪПЧБ write , Й ЮЙФБМУС ВЕЪ ЧЩЪПЧБ read . пФНЕФШФЕ, ЮФП ЬФЙ РТПЗТБННЩ РЙЫХФ Й ЮЙФБАФ ГЕМПЕ ЮЙУМП ЛБЛ УФТПЛХ ФПМШЛП Ч ГЕМСИ ДЕНПОУФТБГЙЙ — ОЕФ ОЙЛБЛПК ОЕПВИПДЙНПУФЙ УПДЕТЦБОЙА ПФПВТБЦБЕНПЗП ЖБКМБ ВЩФШ ФЕЛУФПН. чЩ НПЦЕФЕ УПИТБОЙФШ Й ЧПУУФБОПЧЙФШ РТПЙЪЧПМШОЩК ОБВПТ ДЧПЙЮОЩИ ДБООЩИ.
уПЧНЕУФОЩК ДПУФХР Л ЖБКМХ
тБЪМЙЮОЩЕ РТПГЕУУЩ НПЗХФ ЧЪБЙНПЕДКУФЧПЧБФШ ЙУРПМШЪХС ПВМБУФЙ ПФПВТБЦБЕНПК РБНСФША, УЧСЪБООЩЕ У ПДОЙН Й ФЕН ЦЕ ЖБКМПН. хЛБЦЙФЕ ЖМБЦПЛ MAP_SHARED ДМС ФПЗП, ЮФПВЩ МАВЩЕ ПРЕТБГЙЙ ЪБРЙУЙ Ч ПВМБУФШ РБНСФЙ ОЕНЕДМЕООП РЕТЕДБАФУС ЖБКМХ Й ЧЙДЙНЩН ДТХЗЙН РТПГЕУУБН. еУМЙ чЩ ОЕ ПРТЕДЕМСЕФЕ ЬФПФ ЖМБЦПЛ, Linux НПЦЕФ ВХЖЕТЙЪПЧБФШ ПРЕТБГЙЙ ЪБРЙУЙ РЕТЕД РЕТЕДБЮЕК ЙИ Л ЖБКМХ.
у ДТХЗПК УФПТПОЩ ЧЩ НПЦЕФЕ ЪБУФБЧЙФШ Linux УЙОИТПОЙЪЙТПЧБФШ ВХЖЕТ У ЖБКМПН ОБ ДЙУЛЕ, ЧЩЪЧБЧ msync . еЗП РЕТЧЩЕ ДЧБ РБТБНЕФТБ ПРТЕДЕМСАФ ПВМБУФШ ПФПВТБЦЕООПК РБНСФЙ, ЛБЛ Й ДМС munmap . фТЕФЙК РБТБНЕФТ НПЦЕФ УПДЕТЦБФШ УМЕДХАЭЙЕ ЪОБЮЕОЙС ЖМБЦЛБ:
- MS_ASYNC — ПВОПЧМЕОЙЕ ОБНЕЮБЕФУС, ОП ОЕ ПВСЪБФЕМШОП ЧЩРПМОЕООЩЕФУС РЕТЕД ЧПЪЧТБЭЕОЙЕН ХРТБЧМЕОЙС.
- MS_SYNC — ПВОПЧМЕОЙЕ ОЕРПУТЕДУФЧЕООП; ЧЩЪПЧ ОЕ ЧПЪЧТБЭЕФ ХРТБЧМЕОЙЕ РПЛБ ОЕ ЪБЧЕТЫЙФ УЙОИТПОЙЪБГЙА. MS_SYNC Й MS_ASYNC ОЕ ДПМЦОЩ РТУХФУФЧПЧБФШ ЧНЕУФЕ.
- MS_INVALIDATE — ЧУЕ ДТХЗЙЕ ПФПВТБЦЕОЙС ЖБКМБ ЙЪНЕОЕОЩ ФБЛ, ЮФП ВЩ ПОЙ НПЗМЙ ЧЙДЕФШ НПДЙЖЙГЙТПЧБООЩЕ ЪОБЮЕОЙС.
оБРТЙНЕТ, ЮФПВЩ УВТПУЙФШ ОБ ДЙУЛ ВХЖЕТ ПВЭЕДПУФХРОПЗП ЖБКМ, ПФПВТБЦЕООЩК Ч БДТЕУЕ mem_addr ДМЙОЩ mem_length ВБКФ:
лБЛ Й У УПЧНЕУФОП ЙУРПМШЪХЕНПК РБНСФША, РПМШЪПЧБФЕМЙ ПВМБУФЕК ПФПВТБЦЕООПК РБНСФЙ ДПМЦОЩ УМЕДПЧБФШ РТПФПЛПМХ, ЮФПВЩ ЙЪВЕЦБФШ ХУМПЧЙК ЗПОЛЙ. оБРТЙНЕТ, УЕНБЖПТ НПЦЕФ ЙУРПМШЪПЧБФШУС, ЮФПВЩ РТЕРСФУФЧПЧБФШ ДПУФХРХВПМЕЕ ПДОПЗП РТПГЕУУБ Л ПФПВТБЦЕООПК РБНСФЙ.
юБУФОЩЕ ПФПВТБЦЕОЙС
хЛБЪЩЧБС ЖМБЗ MAP_PRIVATE РТЙ ЧЩЪПЧЕ mmap УПЪДБЕФУС ПВМБУФШ ЛПРЙТПЧБОЙС РТЙ ЪБРЙУЙ. мАВБС ПРЕТБГЙС ЪБРЙУЙ ПФТБЦБЕФУС ФПМШЛП Ч РБНСФЙ ЬФПЗП РТПГЕУУБ; ДТХЗЙЕ РТПГЕУУЩ, ЛПФПТЩЕ ПФПВТБЦБАФ ФПФ ЦЕ УБНЩК ЖБКМ, ОЕ ВХДХФ ЧЙДЕФШ ЙЪНЕОЕОЙС. чНЕУФП ФПЗП, ЮФПВЩ РЙУБФШ ОЕРПУТЕДУФЧЕООП УФТБОЙГЕ, ТБЪДЕМЕООПК ЧУЕНЙ РТПГЕУУБНЙ, РТПГЕУУ РЙЫЕФ ЮБУФОПК ЛПРЙЙ ЬФПК УФТБОЙГЩ. чУЕ РПУМЕДХАЭЙЕ ПРЕТБГЙЙ ЮЙФЕОЙС Й ЪБРЙУЙ РТПГЕУУПН ЙУРПМШЪХАФ ЬФХ ЦЕ УФТБОЙГХ.
дТХЗЙЕ РТЙНЕОЕОЙС mmap
чЩЪПЧ mmap НПЦЕФ ЙУРПМШЪПЧБФШУС Й Ч ГЕМСИ ОЕ УЧСЪБООЩИ У ЧЪБЙНПДЕКУФЧЙЕН РТПГЕУУПЧ. пДОП ЙЪ РТЙНЕОЕОЙК — ЪБНЕОБ ПРЕТБГЙК ДМС ЮФЕОЙС Й ЪБРЙУЙ. оБРТЙНЕТ, ЧНЕУФП ФПЗП, ЮФПВЩ СЧОП ЮЙФБФШ УПДЕТЦЙНПЕ ЖБКМБ Ч РБНСФШ, РТПЗТБННБ НПЗМБ ВЩ ПФПВТБЪЙФШ ЖБКМ Ч РБНСФШ Й РТПУНПФТЕФШ ЬЗП ЙУРПМШЪХС ЮФЕОЙЕ РБНСФЙ. дМС ОЕЛПФПТЩИ РТПЗТБНН, ЬФП ВПМЕЕ ХДПВОП Й НПЦЕФ ТБВПФБФШ ВЩУФТЕЕ, ЮЕН СЧОЩЕ ПРЕТБГЙЙ ЧЧПДБ — ЧЩЧПДБ.
пДОБ НПЭОБС НЕФПДЙЛБ, ЙУРПМШЪХЕНБС ОЕЛПФПТЩНЙ РТПЗТБННБНЙ — ЖПТНЙТПЧБОЙЕ УФТХЛФХТЩ ДБООЩИ Ч ЖБКМЕ ПФПВТБЦЕООПК РБНСФЙ. рТЙ УМЕДХАЭЕН ЪБРХУЛЕ, РТПЗТБННБ ПФПВТБЦБЕФ ФПФ ЖБКМ ОБЪБД Ч РБНСФШ, Й УФТХЛФХТЩ ДБООЩИ ЧПУУФБОПЧМЕОЩ Ч ЙИ РТЕДЩДХЭЕЕЕ УПУФПСОЙЕ. пВТБФЙФЕ ЧОЙНБОЙЕ, ЮФП ХЛБЪБФЕМЙ Ч ЬФЙИ УФТХЛФХТБИ ДБООЩИ ВХДХФ ОЕДПРХУФЙНЩ, ЕУМЙ ПОЙ ЧУЕ ОЕ ХЛБЪЩЧБАФ Ч РТЕДЕМБИ ФПК ПФПВТБЦЕООПК ПВМБУФЙ РБНСФЙ ЙМЙ ЕУМЙ ЖБКМ ПФПВТБЦЕО РП ФЕН ЦЕ БДТЕУБН, ЛПФПТЩЕ ЪБОЙНБМ РЕТЧПОБЮБМШОП.
Источник
Записки программиста
Отображения файла в память под Linux с помощью mmap
26 октября 2015
В прошлый раз мы поговорили об отображении файлов в память при помощи WinAPI, а сегодня разберемся, как то же самое делается под nix-системами, в частности Linux и MacOS. Проверить код под FreeBSD я поленился, но по идее все должно работать и в этой операционной системе. Повторюсь — я почти уверен, что многие читатели сего блога уже знакомы с отображением файлов в память, поэтому пост предназначен для всех остальных читателей.
Укажем необходимые инклуды и объявим структуру FileMapping, хранящую файловый дескриптор, размер файла и указатель на участок памяти с отображением:
#include
#include
#include
#include
struct FileMapping <
int fd ;
size_t fsize ;
unsigned char * dataPtr ;
> ;
Рассмотрим чтение из файла с использованием отображения.
Открываем файл на чтение:
Узнаем размер файла:
size_t fsize = ( size_t ) st. st_size ;
Вызовом mmap создаем отображение файла в память:
Наконец, заполняем структуру FileMapping и возвращаем указатель на нее в качестве результата:
FileMapping * mapping = ( FileMapping * ) malloc ( sizeof ( FileMapping ) ) ;
if ( mapping == nullptr ) <
std :: cerr «fileMappingCreate — malloc failed, fname = »
fname std :: endl ;
munmap ( dataPtr, fsize ) ;
close ( fd ) ;
return nullptr ;
>
mapping — > fd = fd ;
mapping — > fsize = fsize ;
mapping — > dataPtr = dataPtr ;
Теперь по адресу mapping->dataPtr мы можем читать mapping->fsize байт содержимого файла.
Как всегда, не забываем освобождать за собой ресурсы, когда они становятся ненужны:
Вот и все! Сожалею, если вы ожидали чего-то более сложного 🙂 Полную версию исходного кода вы найдете здесь.
Те, кому представленный материал показался слишком простым, могут в качестве домашнего задания сделать следующее:
- Взять одну из *BSD систем и проверить, работает ли код на ней;
- Переписать пример так, чтобы файл можно было не только читать, но и писать в него;
- Выяснить, можно ли менять размер файла, отображенного в память;
- Выяснить, что будет, если создать отображение файла, а затем записать в него что-то через обычный вызов write;
- Погуглить на тему использования mmap в качестве IPC, написать соответствующий пример;
Признаюсь, сам я эти упражнения не выполнял, так как соответствующая задача мне пока что не подворачивалась. Поэтому буду очень вам благодарен, если вы отпишите о результатах их решения в комментариях.
Дополнение: Обратите также внимание на системные вызовы mlock / munlock, msync, madvise и mremap. В определенных типах приложений (например, СУБД) они могут быть очень и очень полезны!
Источник