Saya bingung tentang file yang dipetakan memori, jadi saya punya beberapa pertanyaan yang saya akan sangat senang jika Anda dapat membantu saya.
- Katakanlah saya meramban direktori di sistem file saya dan ada file di direktori ini. Mungkinkah file ini menunjuk ke suatu wilayah di memori utama, alih-alih menunjuk ke suatu wilayah di disk?
- Jika ini mungkin, apakah ini yang kita sebut 'file yang dipetakan memori'?
- Apa artinya memindahkan file semacam itu di sekitar sistem file (yaitu,
mv
memasukkan file seperti itu dari direktori ke direktori lain)? Apa yang saya pahami adalah, karena file tersebut dipetakan memori, proses (es) berinteraksi dengan file selalu menulis ke wilayah yang telah ditentukan dari memori utama, dan ketika kita membuka file itu (misalnya menggunakanvim
), kita membaca wilayah itu dari utama memori (jadi, tidak ada disk yang terlibat). Karenanya, di mana pun kita memindahkan file, itu akan selalu berfungsi dengan benar, bukan? Jika ya, apakah memindahkan file di sekitar sistem file memiliki arti penting? - Apakah ada perintah yang akan memberi tahu jika file dipetakan memori?
- Akhirnya, jika saya membuka file yang dipetakan dengan memori
vim
, buat beberapa perubahan padanya dan simpan dan tutupvim
, apa yang akan terjadi? Apakah perubahan saya hanya akan ditulis ke memori utama? Jika demikian, apakah proses lain yang menggunakan file ini akan melihat perubahan yang baru saja saya buat? Dalam pengalaman saya, proses lain tidak melihat perubahan yang saya buat pada file ketika saya membuat beberapa perubahan pada file tersebutvim
. Apa alasannya?
Jawaban:
File yang dipetakan dengan memori bekerja sebaliknya. Pemetaan memori bukan properti file, tetapi cara untuk mengakses file: suatu proses dapat memetakan konten file (atau subset daripadanya) ke dalam ruang alamatnya. Ini membuatnya lebih mudah untuk membaca dan menulis ke file; melakukannya hanya melibatkan membaca dan menulis dalam memori. File itu sendiri, pada disk, sama seperti file lainnya.
Untuk mengatur ini, proses menggunakan
mmap
fungsi. Ini juga dapat digunakan untuk tujuan lain, seperti berbagi memori antar proses.sumber
mv
.mv
hanya mengubah entri direktori, bukan inode (ketika memindahkan file pada sistem file yang sama).lsof
. Itu tidak hilang sampai proses memanggil munmap (), atau keluar (atau mengganti pemetaan dengan yang berbeda menggunakan mmap (MAP_FIXED) ...)File yang dipetakan dengan memori tidak (harus) didukung oleh memori. Itu bisa dengan sempurna hidup di disk. Sebenarnya, di mana file tinggal bukan milik file itu sendiri tetapi dari sistem file itu berada.
Memetakan file dalam memori adalah operasi proses yang dapat dilakukan untuk memiliki sebagian file yang dimuat dalam memori. Hasilnya terlihat seperti wilayah memori biasa, kecuali ketika proses membaca dari atau menulis ke wilayah ini, itu sebenarnya membaca dari dan menulis ke file. Jika Anda membuka file, memetakannya ke memori, menulis ke sana dan menyimpannya, modifikasi akan dilakukan pada file, pada disk (jika itu hidup pada disk, tentu saja).
Ini dapat digunakan misalnya ketika Anda tahu harus Anda banyak akses untuk melakukan pada file, yang tidak akan berurutan, menjadi penyebabnya dapat lebih mudah dan lebih efisien untuk melakukan membaca dan menulis dalam memori daripada masalah
read
,write
, danllseek
panggilan sistem. Satu-satunya masalah dengan metode ini adalah Anda tidak dapat menggunakannya jika file perlu dibaca atau ditulis oleh beberapa proses secara bersamaan. Hasilnya tidak dapat diprediksi.Saya tidak tahu perintah yang dapat memberi tahu Anda jika file saat ini dipetakan. Anda dapat memeriksa pemetaan suatu proses di
/proc/<pid>/maps
(jika sistem Anda memilikinya).Untuk menjawab pertanyaan kedua Anda, ketika Anda membuka file, bahkan jika Anda memindahkannya di sistem file, proses yang telah dibuka masih dapat menggunakannya. Apa yang terjadi adalah file tidak tergantung dari entri di sistem file. Selama Anda memiliki file yang dibuka, Anda memiliki "pegangan", deskriptor file, yang memungkinkan Anda membaca dan menulis padanya, bahkan jika jalurnya dalam sistem file berubah. File menghilang hanya ketika tidak ada entri di sistem file dan tidak ada proses yang menyimpan deskriptor file di dalamnya.
sumber
/proc/<pid>/maps
. - Asalkan proses mengatakan hidup pada sistem yang memiliki/proc
untuk memulai. OpenBSD tidak, dan FreeBSD sedang menghapusnya. Selain itu, FreeBSD telah/proc/<pid>/map
menggantikan/proc/<pid>/maps
.The
lsof
perintah akan menampilkan semua file yang sedang digunakan oleh sistem. Kolom "FD" akan berisi "mem" jika file tersebut dipetakan memori. Jadi Anda bisa mendapatkan output dari perintah ini untuk nama file yang Anda minati.sumber
lsof -ad mem /path/to/file
lsof -ad mem,txt /path/to/file
sebagai file yang sedang dieksekusi juga memiliki sebagian dari mereka mmap di ruang alamat proses tetapi muncul sepertitxt
dalamlsof
output.Anda tampaknya membingungkan pemetaan memori dengan file dalam sistem file yang berada di memori, bersama dengan konsep-konsep lain seperti bagaimana proses mempertahankan akses ke file bahkan ketika mereka dipindahkan.
Saya akan mengajukan pertanyaan demi pertanyaan untuk melihat apakah saya dapat menjelaskan semuanya.
Itu menunjuk ke memori utama jika itu pada sistem file yang berada di memori, seperti procfs yang biasanya dipasang di / proc, atau sysfs yang ada di / sys, atau tmpfs yang kadang-kadang ada di / tmp.
Tidak. Seperti yang dikatakan stephen-kitt, "pemetaan memori" mengacu pada cara untuk mengakses file dengan "memetakan" pada memori utama dan bekerja dengannya di sana daripada membaca dan menulis bongkahan sekaligus melalui fungsi-fungsi seperti baca () dan menulis().
Jika Anda memindahkannya dalam sistem file yang sama, Anda benar-benar hanya bergerak di sekitar referensi, sebuah inode dari satu direktori ke direktori lain. Jika ada program yang sudah membuka file ini, mereka masih akan mengakses file yang sama karena mereka sudah memiliki inode di tangan melalui deskriptor file. Inilah yang terjadi dengan file table_name.idb yang Anda sebutkan dalam komentar.
Wossname sudah menjawab ini untuk file yang dipetakan memori.
lsof
akan memberi tahu Anda proses mana yang dipetakan memori file.Untuk mengetahui apakah suatu file berada dalam sistem file yang berada di memori, Anda dapat menggunakan
df
ataumount
untuk membuat daftar sistem file dan titik mountnya. Anda hanya perlu tahu jenis sistem file mana yang berada di memori dengan mencarinya (misalnya di wikipedia).Secara pribadi, saya belum menggunakanmmap
fungsi dalam program C, tapi seperti yang saya pahami dari membaca sekilasman mmap
daninfo mmap
, tidak ada keajaiban yang terlibat dalam mempertahankan representasi dalam memori dalam sinkronisasi. Dalam bentuk dasarnya, memanggil mmap menyalin isi file ke memori danmsync
digunakan untuk menulisnya kembali dari memori ke disk. Jika file pada disk berubah, tidak ada yang tersedia untuk mendeteksi itu dan secara otomatis mengubah representasi dalam memori dalam semua proses yang memetakannya.EDIT: Ternyata mmap () benar-benar mencoba untuk menjaga representasi dalam memori tetap sinkron dalam beberapa kondisi. Jika peta hanya dibaca dari, peta itu akan tetap disinkronkan bahkan ketika proses lain menulis ke file. Jika ditulis ke (dengan menetapkan ke wilayah memori), apa yang terjadi tergantung pada bendera MAP_SHARED atau MAP_PRIVATE yang tampaknya wajib diberikan ke mmap (). Jika MAP_PRIVATE disediakan, peta bercabang dari representasi di-disk dan berhenti disinkronkan hingga Anda menggunakan msync (). Jika MAP_SHARED disediakan, maka pembaruan dibuat terlihat oleh proses lain yang memiliki file dipetakan, serta (meskipun ini tidak langsung diperlukan) representasi pada disk.
Saya baru saja membuka vim pada file yang ada
e
, dan menjalankan perintah:w
, sambilinotifywait -m .
menjalankan di terminal lain. Di antara beberapa bagian aneh, ini adalah bagian penting yang saya dapatkaninotifywait
.Vim membuat file baru, dan menghapus yang lama. Mengapa ini dilakukan alih-alih memodifikasi file berada di luar cakupan pertanyaan ini, tetapi intinya adalah bahwa ini adalah file baru dan karenanya memiliki inode baru.
Sekarang, apa yang Anda maksud dengan proses lain menggunakan file ini? Jika yang Anda maksud adalah proses yang memiliki file dibuka saat Anda melakukan ini, tidak mereka tidak akan melihat perubahan. Ini karena, meskipun mereka membuka file dengan jalur yang sama, mereka bukan file yang sama. Jika Anda maksud proses yang dapat membuka file setelah Anda melakukan ini, maka ya mereka akan melihat perubahannya. Mereka akan membuka file baru yang Anda buat.
Penting untuk dicatat bahwa meskipun program tampaknya memiliki file terbuka di antarmuka pengguna, itu tidak berarti bahwa mereka menjaga file tetap terbuka dalam proses. Vim adalah contohnya, seperti yang ditunjukkan di atas.
sumber
write
fungsi ini adalah untuk mengubah data file. Itu mungkin atau mungkin tidak berarti mengubah isi pada disk, tetapi apa pun yang terlibat, itu adalah tanggung jawab sistem file untuk memperbaikinya. Dalam hal ini, itu akan melibatkan memodifikasi halaman memori yang dipetakan dan menandainya kotor.