GNU/Linux >> Tutoriels Linux >  >> Linux

terminaison de processus mmap, msync et linux

Je n'ai pas trouvé de réponse très précise à votre question, j'ai donc décidé d'en ajouter une :

  1. Tout d'abord, concernant la perte de données, l'utilisation de mécanismes d'écriture ou mmap/memcpy permet d'écrire dans le cache de page et de se synchroniser avec le stockage sous-jacent en arrière-plan par le système d'exploitation en fonction de ses paramètres/algorithme de remplacement de page. Par exemple, Linux a vm.dirty_writeback_centisecs qui détermine quelles pages sont considérées comme "anciennes" à vider sur le disque. Désormais, même si votre processus meurt après la réussite de l'appel d'écriture, les données ne seront pas perdues car les données sont déjà présentes dans les pages du noyau qui seront éventuellement écrites dans le stockage. Le seul cas où vous perdriez des données est si le système d'exploitation lui-même plante (panique du noyau, mise hors tension, etc.). Le moyen de s'assurer que vos données ont atteint le stockage serait d'appeler fsync ou msync (pour les régions mmappées) selon le cas.
  2. En ce qui concerne le problème de charge du système, oui, appeler msync/fsync pour chaque requête va considérablement ralentir votre débit, alors ne le faites que si vous le devez. N'oubliez pas que vous vous protégez vraiment contre la perte de données sur les plantages du système d'exploitation, ce qui, je suppose, est rare et probablement quelque chose avec lequel la plupart pourraient vivre. Une optimisation générale consiste à émettre une synchronisation à intervalles réguliers, disons 1 seconde, pour obtenir un bon équilibre.

J'ai trouvé un commentaire de Linus Torvalds qui répond à cette questionhttp://www.realworldtech.com/forum/?threadid=113923&curpostid=114068

Les pages mappées font partie du cache du système de fichiers, ce qui signifie que même si le processus utilisateur qui a modifié cette page meurt, la page est toujours gérée par le noyau et comme tous les accès simultanés à ce fichier passeront par le noyau, d'autres les processus seront servis à partir de ce cache. Dans certains anciens noyaux Linux, c'était différent, c'est la raison pour laquelle certains documents du noyau disent toujours de forcer msync .

EDIT :Merci, RobH a corrigé le lien.

MODIFIER :

Un nouveau drapeau, MAP_SYNC, est introduit depuis Linux 4.15, qui peut garantir la cohérence.

Les mappages de fichiers partagés avec cet indicateur offrent la garantie que, bien qu'une partie de la mémoire soit mappée en écriture dans l'espace d'adressage du processus, elle sera visible dans le même fichier au même décalage même après une panne ou un redémarrage du système.

références :

http://man7.org/linux/man-pages/man2/mmap.2.html rechercher MAP_SYNC dans la page

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


J'ai décidé d'être moins paresseux et de répondre à la question de savoir si les données sont définitivement écrites sur le disque en écrivant du code. La réponse est qu'il sera écrit.

Voici un programme qui se tue brusquement après avoir écrit des données dans un fichier 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);
}

Voici un programme qui valide le fichier résultant après la mort du programme précédent :

#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");
}

J'ai trouvé quelque chose qui ajoute à ma confusion :

munmap n'affecte pas l'objet qui a été mappé, c'est-à-dire que l'appel à munmapne provoque pas l'écriture du contenu de la région mappée sur le fichier disque . La mise à jour du fichier disque pour une région MAP_SHARED se produit automatiquement par l'algorithme de mémoire virtuelle du noyau lorsque nous stockons dans la région mappée en mémoire.

ceci est extrait de Programmation avancée dans l'environnement UNIX® .

à partir de la page de manuel Linux :

MAP_SHARED Partagez ce mappage avec tous les autres processus qui mappent cet objet. Le stockage dans la région est équivalent à l'écriture dans le fichier. Le fichier peut ne pas être mis à jour tant que msync(2) ou munmap(2) n'est pas appelé.

les deux semblent contradictoires. l'APUE est-elle erronée ?


Linux
  1. Comment démarrer la commande Linux en arrière-plan et détacher le processus dans le terminal

  2. Comment installer et configurer Monit sur Linux pour la surveillance des processus

  3. Récupérer l'utilisation du processeur et l'utilisation de la mémoire d'un seul processus sous Linux ?

  4. Quel est le problème avec linux/if.h et net/if.h ?

  5. Utilisation du processeur Linux et historique d'exécution des processus

Comment suspendre un processus et le reprendre plus tard sous Linux

Comment travailler avec le processus de premier plan et d'arrière-plan sous Linux

Comment trouver le PID et le PPID d'un processus sous Linux

Linux Bash Scripting Part5 - Signaux et tâches

Comment tuer les processus sous Linux en utilisant kill, killall et pkill

Comment suivre et tracer un processus Linux