Я запутался в файлах с отображением в памяти, поэтому у меня есть пара вопросов, которые я был бы очень рад, если бы вы могли мне помочь.
- Допустим, я перехожу к каталогу в моей файловой системе, и в этом каталоге есть файл. Возможно ли, чтобы этот файл указывал на область в основной памяти, а не на область на диске?
- Если это возможно, это то, что мы называем «файл с отображением в памяти»?
- Каков смысл перемещения такого файла по файловой системе (то есть переноса
mv
такого файла из одного каталога в другой)? Что я понимаю, так как файл отображен в памяти, процесс (ы), взаимодействующий с файлом, всегда записывает в предопределенную область основной памяти, и когда мы открываем этот файл (например, используяvim
), мы читаем эту область главного память (значит, диск не задействован). Следовательно, независимо от того, куда мы перемещаем файл, он всегда будет работать правильно, верно? Если да, имеет ли какое-либо значение перемещение файла вокруг файловой системы? - Есть ли команда, которая скажет, сопоставлен ли файл с памятью?
- Наконец, если я открою файл с отображением в памяти
vim
, внесу в него некоторые изменения, сохраню и закроюvim
, что произойдет? Будут ли мои изменения просто записываться в основную память? Если это так, другие процессы, использующие этот файл, увидят изменения, которые я только что сделал? По моему опыту, другие процессы не видели изменений, которые я внес в файл, когда я сделал некоторые изменения в файле сvim
. Что является причиной этого?
Ответы:
Файлы с отображением в памяти работают наоборот. Отображение памяти - это не свойство файла, а способ доступа к файлу: процесс может отобразить содержимое файла (или его подмножество) в его адресное пространство. Это облегчает чтение и запись в файл; это просто включает чтение и запись в память. Сам файл на диске такой же, как и любой другой файл.
Чтобы настроить это, процессы используют
mmap
функцию. Это также может быть использовано для других целей, таких как разделение памяти между процессами.источник
mv
.mv
просто изменяют записи каталога, а не inode (когда он перемещает файлы в одной файловой системе).lsof
. Он не исчезнет, пока процесс не вызовет munmap () или не выйдет (или не заменит отображение другим, используя mmap (MAP_FIXED) ...)Файл с отображением в памяти (не обязательно) не поддерживается памятью. Он может прекрасно жить на диске. На самом деле, место существования файла - это не свойство самого файла, а файловой системы, в которой он находится.
Отображение файла в памяти - это операция, которую процесс может выполнить, чтобы часть файла была загружена в память. Результат выглядит как обычная область памяти, за исключением того, что когда процесс выполняет чтение или запись в эту область, он фактически выполняет чтение и запись в файл. Если вы откроете файл, отобразите его в памяти, запишите в него и сохраните его, изменение будет выполнено для файла, на диске (если, конечно, он находится на диске).
Это может быть использовано, например , когда вы знаете , есть много доступов делать на файл, который не собирается быть последовательным, быть причиной может быть проще и эффективнее делать операции чтения и записи в память , чем проблемы
read
,write
, иllseek
системные звонки. Единственная проблема этого метода заключается в том, что вы не можете использовать его, если файл должен быть прочитан или записан несколькими процессами одновременно. Результаты будут непредсказуемыми.Я не знаю команды, которая может сказать вам, если файл в настоящее время сопоставлен. Тем не менее, вы можете проверить отображение процесса в
/proc/<pid>/maps
(если ваша система имеет его).Чтобы ответить на ваш второй вопрос, когда вы открываете файл, даже если вы перемещаете его в файловой системе, процессы, которые открыли его, все равно могут его использовать. Что происходит, так это то, что файл не зависит от его записей в файловых системах. Пока у вас открыт файл, у вас есть «дескриптор», дескриптор файла, который позволяет вам читать и писать в него, даже если его путь в файловой системе изменяется. Файл исчезает только тогда, когда у него нет записи в файловой системе, и ни один процесс не содержит дескриптор файла.
источник
/proc/<pid>/maps
. - При условии, что указанный процесс живет в системе, которая/proc
должна начинаться с. OpenBSD этого не делает, а FreeBSD постепенно его прекращает. Кроме того, FreeBSD имеет/proc/<pid>/map
вместо/proc/<pid>/maps
.Команда
lsof
покажет вам все файлы, которые в данный момент используются системой. Столбец «FD» будет содержать «mem», если файл отображен в память. Таким образом, вы можете получить выходные данные этой команды для имени файла, который вас интересует.источник
lsof -ad mem /path/to/file
lsof -ad mem,txt /path/to/file
поскольку выполняемые файлы также имеют части, отображаемые в адресном пространстве процесса, но отображаются какtxt
вlsof
выходных данных.Вы, кажется, путаете отображение памяти с файлами в файловых системах, находящихся в памяти, наряду с другими понятиями, такими как то, как процессы поддерживают доступ к файлам, даже когда они перемещаются.
Я пойду вопрос за вопросом, чтобы посмотреть, смогу ли я все прояснить.
Он указывает на основную память, если она находится в файловой системе, находящейся в памяти, например, procfs, которая обычно монтируется в / proc, или sysfs, которая находится в / sys, или tmpfs, которая иногда находится в / tmp.
Нет. Как сказал Стивен-Китт, «отображение памяти» относится к способу доступа к файлу путем «сопоставления» его с основной памятью и работы с ним там, а не для чтения и записи фрагментов одновременно с помощью таких функций, как read () и записывать().
Если вы перемещаете его внутри одной и той же файловой системы, вы на самом деле просто перемещаетесь по ссылке, индексу из одного каталога в другой. Если есть программы, которые уже открыли этот файл, они все равно будут обращаться к тому же файлу, потому что у них уже есть inode под дескриптором файла. Это то, что произошло с файлом table_name.idb, который вы упомянули в комментарии.
Wossname уже ответил на это для отображенных в памяти файлов.
lsof
скажет вам, какие процессы отображены в памяти файла.Чтобы узнать, находится ли файл в файловой системе, находящейся в памяти, вы можете использовать
df
илиmount
для вывода списка файловых систем и их точек монтирования. Вам просто нужно знать, какие типы файловых систем находятся в памяти, просматривая их (например, в википедии).Лично я не использовал этуmmap
функцию в программе на C, но, насколько я понимаю, из-за скиммингаman mmap
иinfo mmap
никакой магии не требуется для поддержания представления в памяти в синхронизации. В своей основной форме вызов mmap копирует содержимое файла в память иmsync
используется для записи его обратно из памяти на диск. Если файл на диске изменяется, нет ничего, что могло бы обнаружить это и автоматически изменить представление в памяти во всех процессах, которые его отобразили.РЕДАКТИРОВАТЬ: Оказывается, что mmap () на самом деле пытается синхронизировать представление в памяти при некоторых условиях. Если карта только для чтения, она будет синхронизирована, даже когда другие процессы будут записывать в файл. Если он записан (путем присвоения области памяти), то, что происходит, зависит от того, какой из явно обязательных флагов MAP_SHARED или MAP_PRIVATE предоставлен mmap (). Если указано MAP_PRIVATE, карта разветвляется из представления на диске и перестает синхронизироваться до тех пор, пока вы не используете msync (). Если предоставляется MAP_SHARED, то обновления становятся видимыми для других процессов, которым сопоставлен файл, а также (хотя это не обязательно необходимо) представление на диске.
Я просто открыл vim для существующего файла
e
и выполнил команду:w
,inotifywait -m .
запустив другой терминал. Среди некоторых странных моментов, это важная часть, которую я получилinotifywait
.Vim создает новый файл и удаляет старый. Почему это происходит вместо изменения файла, выходит за рамки этого вопроса, но дело в том, что это новый файл и, следовательно, новый индекс.
Теперь, что вы подразумеваете под другими процессами, использующими этот файл? Если вы имеете в виду процессы, которые открыли файл во время этого процесса, нет, они не увидят изменений. Это потому, что, хотя они открыли файл с одинаковым путем, они не являются тем же файлом. Если вы имеете в виду процессы, которые могут открыть файл после того, как вы это сделали, то да, они увидят изменения. Они будут открывать новый файл, который вы создали.
Важно отметить, что, хотя программы могут показаться, что файл открыт в пользовательском интерфейсе, это не обязательно означает, что они сохраняют файл открытым в процессе. Vim является примером этого, как показано выше.
источник
write
функции - изменить данные файла. Это может означать, а может и не означать изменение содержимого на диске, но независимо от того, что оно включает, файловая система несет ответственность за его правильное выполнение. В этом случае потребуется изменить отображенную страницу памяти и пометить ее как грязную.