ich habe in einem Programm die Notwendigkeit, einige ziemlich gro�e
Datenbl�cke (ca. 2-4 Bl�cke, jeweils ca. 1-2 GB) zu verwalten
(wahlfreier Zugriff).
Daf�r sehe ich im Prinzip zwei M�glichkeiten:
1. Ich alloziere einfach gen�gend gro�e Speicherbereiche und verwende
sie. Wenn der (physische) Speicher ausgeht, wird ja sowieso in den
Swap ausgelagert.
2. Ich lege f�r die Bl�cke Temp-Dateien an und verwende mmap() f�r den
direkten Zugriff. Wenn noch gen�gend physischer Speicher vorhanden ist,
erfolgt das Datenkopieren sowieso im Cache.
Auf den ersten Blick erscheinen mir beide M�glichkeiten etwa
gleichwertig: solange nur genug physischer Speicher vorhanden ist,
erfolgen die Operationen potentiell eher im RAM als auf der
Festplatte.
Im ersten Fall bin ich aber in der Gr��e auf das limitiert, was der
(sp�tere) Benutzer als Swap angelegt hat, w�hrend im zweiten Fall im
Grunde nur das Dateisystem ein Limit darstellt (?). Daf�r wird man
wohl im zweiten Fall "gegen" das OS arbeiten, welches aus
Sicherheitsgr�nden immer mal (sinnlos) Daten auf die Platte schreiben
wird --> eigentlich erscheint mit die erste L�sung als einzig
sinnvolle und die zweite als (von absoluten Ausnahmen abgesehen)
unsinnig.
Was mich nur stutzig macht: warum legen dann Programme �berhaupt
tempor�re (auf den Programmlauf beschr�nkte) Dateien an? Der einzige
Grund, der mit einfiele, w�re IPC, aber selbst da ist ein
Zwischenspeicher auf der Platte sicher keine gute Wahl.
Gibt es einen Grund, *nicht* malloc() zu nehmen, sondern mmap()?
Viele Gr��e
Ole
Das malloc() ist für viele kleine Allokationen optimiert und sollte
unter anderem auch defragmentieren. Könnte aber ein Problem
werden, wenn es dabei einen GB großen Block anfängt zu schieben.
>
> Im ersten Fall bin ich aber in der Größe auf das limitiert, was der
> (spätere) Benutzer als Swap angelegt hat, während im zweiten Fall im
> Grunde nur das Dateisystem ein Limit darstellt (?). Dafür wird man
> wohl im zweiten Fall "gegen" das OS arbeiten, welches aus
> Sicherheitsgründen immer mal (sinnlos) Daten auf die Platte schreiben
Es lohnt sich evtl. via MAP_PRIVATE mmap() zu sagen, dass Änderungen
für andere Prozesse nicht sichtbar sein müssen. Daneben gibt es auch
systemspezifische Erweiterungen, die mehr feintüning erlauben.
>
> Was mich nur stutzig macht: warum legen dann Programme überhaupt
> temporäre (auf den Programmlauf beschränkte) Dateien an? Der einzige
> Grund, der mit einfiele, wäre IPC, aber selbst da ist ein
> Zwischenspeicher auf der Platte sicher keine gute Wahl.
>
Bei IPC macht man es aus Sicherheitsgründen.
Es greifen die Zugriffsrechte, die durch das Datei-System abgebildet
werden. I-Nodes müssen dabei nicht unbedingt durch ein Fest-
Speichermedium getragen werden. Z.B. auf meinen Solaris ist /var/run
und /tmp mittels Swap-Dateisystem gemountet.
Gruesse,
Frank.
Also mir fallen da nur kopfnickend die uralten Programmiererspr�che ein
"keep it simple" und "ein Mann muss tun, was ein Mann tun muss". Du
brauchst ziemlich gro�e Datenbl�cke im RAM f�r den wahlfreien Zugriff?
Einfach allozieren, benutzen und darauf vertrauen, dass andere Leute
auch ihre Arbeit richtig machen. Erst wenn es eindeutig nicht vern�nftig
l�uft, den Fehler suchen und mit w�rg-arounds anfangen, dann aber auch
gezielt pr�fen - mmap() k�nnte eine Alternative, muss aber nicht besser
sein, das weiss man erst, wenn es l�uft.
Gru�,
Ed
Ja.
z.B.
- Du m�chtest, dass Deine Daten auch nach dem Programmende noch da sind.
- Du m�chtest, dass Deine Daten auch nach einem Absturz noch da sind.
- Du m�chtest von mehreren Prozessen aus darauf zugreifen.
- Du brauchst einfache Debug-M�glichkeiten f�r die Daten.
Gib mmap() eine Chance. Es hat sie verdient. Ich habe (vor Jahren) die
Umstellung von Shared-Memory auf mmap() unter AIX 4.2.1
getestet. Ausl�ser war, dass ein Prozess, der Zugriff auf das
Shared-Memory hatte und "h�ngen blieb", das Anlegen eines neuen
Bereiches mit gleichem Key wirksam unterdr�ckte. Um robuster zu
werden habe ich die Daten eine "mmaped" Datei gepackt und mal geschaut,
was so passiert. Zu meinem gro�en Erstaunen war gar keine nennenswerte
zus�tzliche Plattenaktivit�t feststellbar. Dennoch war der Inhalt immer
dann vollst�ndig auf der Platte, wenn ich die entscheidenden Prozesse
einfach mal mit einem kill beschossen habe. Das ist sehr n�tzlich, wenn
man ein sinnvolles Nachstarten von evtl. abgest�rzten Prozessen -
m�glichst *ohne* Datenverlust - unterst�tzt (Graceful Degradation).
Probier es doch einmal aus.
Gru�
Jochen
--
"Wer die Freiheit aufgibt, um Sicherheit zu gewinnen,
der wird am Ende beides verlieren"
>> Gibt es einen Grund, *nicht* malloc() zu nehmen, sondern mmap()?
> z.B.
> - Du möchtest, dass Deine Daten auch nach dem Programmende noch da sind.
> - Du möchtest, dass Deine Daten auch nach einem Absturz noch da sind.
> - Du möchtest von mehreren Prozessen aus darauf zugreifen.
> - Du brauchst einfache Debug-Möglichkeiten für die Daten.
> Gib mmap() eine Chance. Es hat sie verdient.
Nach dem Buch von Herold: Linux Sytemprogrammierung
enthält das dritte Argument Schutz folgende bits:
PROT_READ, PROT_WRITE und PROT_EXEC.
Wenn ich alle drei bits setze,
und Maschinencode hineinkopiere,
darf ich ihn dann definitiv ausführen
(z.B. mit pointer to function?)
Hermann
der das gerne irgendwann mal verwenden möchte.
Das ist, wenn ich mich jetzt recht entsinne, eine Eigenschaft, die
versprochen wird. Schau einmal die man-Pages an.
�hnlich, wie das BS beim Ableben eines Prozesses alle noch offenen
Dateien (irgendwie) schlie�t, kann es auch daf�r sorgen, dass
(sp�testens) jetzt der Inhalt des Speichers auf die Platte (naja, da ist
dann evtl. noch das Dateisystem und und und dazwischen mit Puffern und
so) kommt.
Ich war damals[TM] sehr erstaunt, wie robust und sparsam die
Implementierung (freilich unter AIX) war.
> Jochen L�bbers schrieb:
>
>> Das ist, wenn ich mich jetzt recht entsinne, eine Eigenschaft,
>> die versprochen wird. Schau einmal die man-Pages an.
>
> Glaub ich nicht; w�re ja extrem ineffizient wenn nach jeder
> Schreiboperation in den Speicher gleich das Abbild auf der
> Platte aktualisiert w�rde.
Mu� ja auch nicht. Der Kernel kann das machen, bevor er den Proze�
(bzw. die von ihm belegten Seiten) zur Wiederverwendung freigibt.
Ja, Gedankenfehler. Freigegebene Blöcke werden wohl nicht
verschoben, sondern eher zugehörige Verwaltungsinformation
gemerged. Da aber ein Memory-Manager für kleine Objekte
kaum einen Listen-Knoten pro Allokation bereitstellen kann,
würde ich mir das problematisch vorstellen, wenn man sehr
große Blöcke allociert.
Ist das nicht genau das, was der dynamische Linker und dlopen intern
verwenden?
Gerald Breuer schrieb:
> Jochen L�bbers schrieb:
>
>> z.B.
>> - Du m�chtest, dass Deine Daten auch nach dem Programmende noch da sind.
>
> Kann das garantiert werden? Dazu m�sste der Speicherbereich
> doch bei jedem Zugriff zur�ckgeschrieben werden, oder?
Bei einem Systemabsturz nur, wenn man msync(2) verwendet. Ansonsten: Ja.
mmap(2) ist mit 4.2BSD eingef�hrt worden. Der Hindergrund war, dass
UNIX-Systeme f�r Datenbanken wenig geeignet waren. Bei einem read(2)
oder write(2) werden die Daten immer zwischen einem Puffer des
Betriebssystems und dem User-Space der Applikation kopiert. Mit mmap(2)
hat man einen Weg geschaffen dies zu zu umgehen, indem die Funktion die
Plattenpuffer direkt in den Speicherbereich des Prozesses einblendet.
Das Kopieren f�llt dann weg. Wenn man nun in den Puffer schreibt so wird
dieser als "Dirty" markiert und beim n�chsten Platten-Sync in die Datei
zur�ckgeschrieben. Das ist genau so wie dies auch bei einem write(2) der
Fall ist.
Letztlich ist mmap(2) f�r einen direkteren und schnelleren Zugriff auf
Dateien konzipiert worden und nicht f�r das reservieren von
Speicherbereichen. Ich w�rde Speicher vorzugsweise immer mit malloc(3)
reservieren, wenn ich diesen nicht unbedingt persistent auf der Platte
ben�tige. Es kostet h�chstens Performance, wenn genug Hauptspeicher zur
Verf�gung steht.
Ansonsten k�nnte ich mir noch vorstellen, dass man mittels mmap(2) die
2GB-Grenze bei 32-Bit-Systemen umgeht, indem man immer nur einen Teil
des Speichers in die Applikation einblendet.
Bis denne ...
Marcus