GNU/Linux >> Znalost Linux >  >> Linux

ukončení procesů mmap, msync a linux

Nenašel jsem velmi přesnou odpověď na vaši otázku, tak jsem se rozhodl přidat ještě jednu:

  1. Zaprvé o ztrátě dat, pomocí mechanismů zápisu nebo mmap/memcpy se oba zapisují do mezipaměti stránky a jsou synchronizovány do základního úložiště na pozadí OS na základě jeho nastavení/algo nahrazování stránek. Například linux má vm.dirty_writeback_centisecs, který určuje, které stránky jsou považovány za "staré" pro vyprázdnění na disk. Nyní, i když váš proces po úspěšném zápisu skončí, data se neztratí, protože data jsou již přítomna na stránkách jádra, které budou nakonec zapsány do úložiště. Jediným případem, kdy byste přišli o data, je pád samotného OS (panikaření jádra, vypnutí atd.). Způsob, jak se absolutně ujistit, že vaše data dosáhla úložiště, by bylo volání fsync nebo msync (pro mmapované oblasti), podle toho, o jaký případ jde.
  2. Pokud jde o problém se zatížením systému, ano, volání msync/fsync pro každý požadavek drasticky zpomalí vaši propustnost, takže to dělejte, pouze pokud musíte. Pamatujte, že skutečně chráníte před ztrátou dat při selhání operačního systému, což bych předpokládal, že je vzácné a pravděpodobně něco, s čím by většina mohla žít. Jednou z obecných optimalizací je provádět synchronizaci v pravidelných intervalech, řekněme 1 sekundu, abyste získali dobrou rovnováhu.

Našel jsem komentář od Linuse Torvaldse, který odpovídá na tuto otázkuhttp://www.realworldtech.com/forum/?threadid=113923&curpostid=114068

Mapované stránky jsou součástí mezipaměti souborového systému, což znamená, že i když uživatelský proces, který provedl změnu na této stránce, zemře, stránka je stále spravována jádrem, a protože všechny souběžné přístupy k tomuto souboru projdou jádrem, ostatní procesy budou obsluhovány z této mezipaměti. V některých starých linuxových jádrech to bylo jiné, to je důvod, proč některé dokumenty jádra stále říkají vynutit msync .

EDIT:Díky, RobH opravil odkaz.

EDIT:

Od Linuxu 4.15 je zaveden nový příznak MAP_SYNC, který může zaručit koherenci.

Mapování sdílených souborů s tímto příznakem poskytuje záruku, že zatímco je část paměti zapisovatelně mapována v adresovém prostoru procesu, bude viditelná ve stejném souboru se stejným offsetem i po zhroucení systému nebo po restartování.

reference:

http://man7.org/linux/man-pages/man2/mmap.2.html hledat MAP_SYNC na stránce

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


Rozhodl jsem se být méně líný a na otázku, zda se data zapisují na disk definitivně, odpovím napsáním nějakého kódu. Odpověď je, že to bude napsáno.

Zde je program, který se po zapsání některých dat do souboru mmap'd náhle zabije:

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

Zde je program, který ověří výsledný soubor poté, co je předchozí program mrtvý:

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

Našel jsem něco, co přispělo k mému zmatku:

munmap neovlivňuje objekt, který byl mapován, to znamená, že volání munmap nezpůsobí zapsání obsahu mapované oblasti do souboru na disku . Aktualizace diskového souboru pro oblast MAP_SHARED probíhá automaticky pomocí algoritmů virtuální paměti jádra, které ukládáme do oblasti mapované paměti.

toto je výňatek z Pokročilého programování v prostředí UNIX® .

z linuxové manuálové stránky:

MAP_SHARED Sdílejte toto mapování se všemi ostatními procesy, které mapují tento objekt. Ukládání do regionu je ekvivalentní zápisu do souboru. Soubor nemusí být ve skutečnosti aktualizován, dokud nebude zavoláno msync(2) ormunmap(2).

ti dva vypadají protichůdně. je APUE špatně?


Linux
  1. Přehled procesu UNIX (uvnitř procesu Linux a typy procesů)

  2. Načíst využití CPU a paměti jedním procesem v Linuxu?

  3. Co je špatného na linux/if.h a net/if.h?

  1. Jak spustit příkaz Linux na pozadí a odpojit proces v terminálu

  2. Jak najít a zabít zombie proces v Linuxu

  3. Linux:Zobrazení a ukončení odmítnutého procesu

  1. Jak nainstalovat a nakonfigurovat Monit na Linuxu pro monitorování procesů

  2. Linux:Najděte a zabijte zombie procesy

  3. Existuje nějaký způsob, jak zablokovat LD_PRELOAD a LD_LIBRARY_PATH na Linuxu?