GNU/Linux >> LINUX-Kenntnisse >  >> Linux

mmap-, msync- und Linux-Prozessbeendigung

Ich habe keine sehr genaue Antwort auf Ihre Frage gefunden, also habe ich beschlossen, eine weitere hinzuzufügen:

  1. Erstens zum Datenverlust:Schreib- oder mmap/memcpy-Mechanismen verwenden sowohl Schreibvorgänge in den Seitencache als auch werden vom Betriebssystem basierend auf den Seitenersetzungseinstellungen/-algos im Hintergrund mit dem zugrunde liegenden Speicher synchronisiert. Zum Beispiel hat Linux vm.dirty_writeback_centisecs, das bestimmt, welche Seiten als "alt" gelten und auf die Festplatte geleert werden. Selbst wenn Ihr Prozess nach erfolgreichem Schreibaufruf abbricht, gehen die Daten nicht verloren, da die Daten bereits in Kernelseiten vorhanden sind, die schließlich in den Speicher geschrieben werden. Der einzige Fall, in dem Sie Daten verlieren würden, ist, wenn das Betriebssystem selbst abstürzt (Kernelpanik, Ausschalten usw.). Um absolut sicherzustellen, dass Ihre Daten den Speicher erreicht haben, rufen Sie je nach Fall fsync oder msync (für mmappte Regionen) auf.
  2. Was die Systemlast betrifft, ja, das Aufrufen von msync/fsync für jede Anfrage wird Ihren Durchsatz drastisch verlangsamen, also tun Sie das nur, wenn Sie müssen. Denken Sie daran, dass Sie sich wirklich vor Datenverlust bei Betriebssystemabstürzen schützen, was meiner Meinung nach selten ist und wahrscheinlich etwas, mit dem die meisten leben könnten. Eine allgemeine Optimierung besteht darin, in regelmäßigen Abständen, z. B. 1 Sekunde, eine Synchronisierung durchzuführen, um eine gute Balance zu erhalten.

Ich habe einen Kommentar von Linus Torvalds gefunden, der diese Frage beantwortethttp://www.realworldtech.com/forum/?threadid=113923&curpostid=114068

Die abgebildeten Seiten sind Teil des Dateisystem-Cache, was bedeutet, dass selbst wenn der Benutzerprozess, der eine Änderung an dieser Seite vorgenommen hat, stirbt, die Seite immer noch vom Kernel verwaltet wird und alle gleichzeitigen Zugriffe auf diese Datei durch den Kernel gehen, andere Prozesse werden aus diesem Cache bedient. In einigen alten Linux-Kerneln war das anders, das ist der Grund, warum einige Kernel-Dokumente immer noch sagen, dass msync erzwungen werden soll .

BEARBEITEN:Danke, RobH hat den Link korrigiert.

BEARBEITEN:

Seit Linux 4.15 wird ein neues Flag, MAP_SYNC, eingeführt, das die Kohärenz gewährleisten kann.

Shared-File-Mappings mit diesem Flag stellen sicher, dass ein Teil des Speichers, obwohl er im Adressraum des Prozesses beschreibbar zugeordnet ist, in derselben Datei mit demselben Offset sichtbar ist, selbst nachdem das System abstürzt oder neu gestartet wird.

Referenzen:

http://man7.org/linux/man-pages/man2/mmap.2.html suchen Sie MAP_SYNC auf der Seite

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


Ich beschloss, weniger faul zu sein und die Frage, ob die Daten auf die Festplatte geschrieben werden, endgültig zu beantworten, indem ich etwas Code schrieb. Die Antwort ist, dass es geschrieben wird.

Hier ist ein Programm, das sich abrupt beendet, nachdem es einige Daten in eine mmap-Datei geschrieben hat:

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

Hier ist ein Programm, das die resultierende Datei validiert, nachdem das vorherige Programm tot ist:

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

Ich habe etwas gefunden, das meine Verwirrung noch verstärkt:

munmap wirkt sich nicht auf das zugeordnete Objekt aus, das heißt, der Aufruf von munmap bewirkt nicht, dass der Inhalt der zugeordneten Region in die Plattendatei geschrieben wird . Die Aktualisierung der Festplattendatei für eine MAP_SHARED-Region erfolgt automatisch durch den virtuellen Speicheralgorithmus des Kernels, wenn wir in der speicherabgebildeten Region speichern.

dies ist ein Auszug aus Erweiterte Programmierung in der UNIX®-Umgebung .

von der Linux-Manpage:

MAP_SHARED Dieses Mapping mit allen anderen Prozessen teilen, die dieses Objekt abbilden. Das Speichern in der Region entspricht dem Schreiben in die Datei. Die Datei wird möglicherweise erst aktualisiert, wenn msync(2) oder munmap(2) aufgerufen werden.

die beiden scheinen widersprüchlich. ist APUE falsch?


Linux
  1. So starten Sie den Linux-Befehl im Hintergrund und trennen den Prozess im Terminal

  2. So finden und töten Sie den Zombie-Prozess in Linux

  3. So installieren und konfigurieren Sie Monit unter Linux für die Prozessüberwachung

  4. Was ist falsch an linux/if.h und net/if.h?

  5. Linux:Disowned-Prozess anzeigen und beenden

So unterbrechen Sie einen Prozess und setzen ihn später in Linux fort

So arbeiten Sie mit Vordergrund- und Hintergrundprozessen unter Linux

So finden Sie die PID und PPID eines Prozesses in Linux

Linux Bash Scripting Part5 – Signale und Jobs

So beenden Sie Prozesse in Linux mit kill, killall und pkill

So verfolgen und verfolgen Sie einen Linux-Prozess