GNU/Linux >> Belajar Linux >  >> Linux

penghentian proses mmap, msync dan linux

Saya tidak menemukan jawaban yang tepat untuk pertanyaan Anda, jadi putuskan untuk menambahkan satu lagi:

  1. Pertama tentang kehilangan data, menggunakan mekanisme tulis atau mmap/memcpy keduanya menulis ke cache halaman dan disinkronkan ke penyimpanan dasar di latar belakang oleh OS berdasarkan pengaturan/algo penggantian halamannya. Misalnya linux memiliki vm.dirty_writeback_centisecs yang menentukan halaman mana yang dianggap "lama" untuk di-flush ke disk. Sekarang bahkan jika proses Anda mati setelah panggilan tulis berhasil, data tidak akan hilang karena data sudah ada di halaman kernel yang pada akhirnya akan ditulis ke penyimpanan. Satu-satunya kasus Anda akan kehilangan data adalah jika OS itu sendiri macet (panik kernel, matikan dll). Cara untuk benar-benar memastikan data Anda telah mencapai penyimpanan adalah dengan memanggil fsync atau msync (untuk wilayah yang di-mmapped) seperti yang mungkin terjadi.
  2. Tentang masalah beban sistem, ya, memanggil msync/fsync untuk setiap permintaan akan memperlambat throughput Anda secara drastis, jadi lakukan itu hanya jika perlu. Ingat Anda benar-benar melindungi dari kehilangan data pada OS crash yang menurut saya jarang terjadi dan mungkin sesuatu yang paling bisa diterima. Salah satu pengoptimalan umum yang dilakukan adalah melakukan sinkronisasi secara berkala, katakanlah 1 detik untuk mendapatkan keseimbangan yang baik.

Saya menemukan komentar dari Linus Torvalds yang menjawab pertanyaan inihttp://www.realworldtech.com/forum/?threadid=113923&curpostid=114068

Halaman yang dipetakan adalah bagian dari cache sistem file, yang berarti bahwa meskipun proses pengguna yang membuat perubahan pada halaman tersebut mati, halaman tersebut masih dikelola oleh kernel dan karena semua akses bersamaan ke file tersebut akan melalui kernel, selain itu proses akan dilayani dari cache itu. Di beberapa kernel Linux lama itu berbeda, itulah alasan mengapa beberapa dokumen kernel masih mengatakan untuk memaksa msync .

EDIT:Terima kasih RobH memperbaiki tautannya.

EDIT:

Bendera baru, MAP_SYNC, diperkenalkan sejak Linux 4.15, yang dapat menjamin koherensi.

Pemetaan file bersama dengan flag ini memberikan jaminan bahwa sementara beberapa memori dipetakan secara tertulis di ruang alamat proses, itu akan terlihat di file yang sama pada offset yang sama bahkan setelah sistem macet atau di-boot ulang.

referensi:

http://man7.org/linux/man-pages/man2/mmap.2.html cari MAP_SYNC di halaman

https://lwn.net/Articles/731706/


Saya memutuskan untuk tidak terlalu malas dan menjawab pertanyaan apakah data ditulis ke disk secara definitif dengan menulis beberapa kode. Jawabannya adalah itu akan ditulis.

Berikut adalah program yang mati sendiri secara tiba-tiba setelah menulis beberapa data ke file mmap:

#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

typedef struct {
  char data[100];
  uint16_t count;
} state_data;

const char *test_data = "test";

int main(int argc, const char *argv[]) {
  int fd = open("test.mm", O_RDWR|O_CREAT|O_TRUNC, (mode_t)0700);
  if (fd < 0) {
    perror("Unable to open file 'test.mm'");
    exit(1);
  }
  size_t data_length = sizeof(state_data);
  if (ftruncate(fd, data_length) < 0) {
    perror("Unable to truncate file 'test.mm'");
    exit(1);
  }
  state_data *data = (state_data *)mmap(NULL, data_length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_POPULATE, fd, 0);
  if (MAP_FAILED == data) {
    perror("Unable to mmap file 'test.mm'");
    close(fd);
    exit(1);
  }
  memset(data, 0, data_length);
  for (data->count = 0; data->count < 5; ++data->count) {
    data->data[data->count] = test_data[data->count];
  }
  kill(getpid(), 9);
}

Berikut adalah program yang memvalidasi file yang dihasilkan setelah program sebelumnya mati:

#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>

typedef struct {
  char data[100];
  uint16_t count;
} state_data;

const char *test_data = "test";

int main(int argc, const char *argv[]) {
  int fd = open("test.mm", O_RDONLY);
  if (fd < 0) {
    perror("Unable to open file 'test.mm'");
    exit(1);
  }
  size_t data_length = sizeof(state_data);
  state_data *data = (state_data *)mmap(NULL, data_length, PROT_READ, MAP_SHARED|MAP_POPULATE, fd, 0);
  if (MAP_FAILED == data) {
    perror("Unable to mmap file 'test.mm'");
    close(fd);
    exit(1);
  }
  assert(5 == data->count);
  unsigned index;
  for (index = 0; index < 4; ++index) {
    assert(test_data[index] == data->data[index]);
  }
  printf("Validated\n");
}

Saya menemukan sesuatu yang menambah kebingungan saya:

munmap tidak memengaruhi objek yang dipetakanyaitu, panggilan ke munmap tidak menyebabkan konten wilayah yang dipetakan ditulis ke file disk . Pembaruan file disk untuk wilayah MAP_SHARED terjadi secara otomatis oleh algoritme memori virtual kernel saat kami menyimpan ke dalam wilayah yang dipetakan memori.

ini dikutip dari Pemrograman Lanjutan di Lingkungan UNIX® .

dari halaman manual linux:

MAP_SHARED Bagikan pemetaan ini dengan semua proses lain yang memetakan objek ini. Menyimpan ke wilayah sama dengan menulis ke file. File mungkin tidak benar-benar diperbarui hingga msync(2) atau munmap(2) dipanggil.

keduanya tampak kontradiktif. apakah APUE salah?


Linux
  1. Ambil penggunaan CPU dan penggunaan memori dari satu proses di Linux?

  2. Apa yang salah dengan linux/if.h dan net/if.h?

  3. Linux:Lihat dan matikan proses yang tidak diakui

  1. Apakah ada cara untuk memblokir LD_PRELOAD dan LD_LIBRARY_PATH di Linux?

  2. Linux:Bagaimana cara mengetahui di mana suatu proses dimulai dan bagaimana proses itu dimulai?

  3. Penggunaan CPU Linux dan Riwayat Eksekusi Proses

  1. Cara Memulai Perintah Linux di Latar Belakang dan Melepaskan Proses di Terminal

  2. Cara Menemukan dan Membunuh Proses Zombie di Linux

  3. Cara Menginstal dan Mengonfigurasi Monit di Linux untuk Pemantauan Proses