Kopieren von Daten aus einem Shared-Memory-Mapped-Objekt mit sendfile () / fcopyfile ()

9

Ist es möglich - und wenn es so umsichtig ist - sendfile() (oder sein Darwin / BSD-Cousin fcopyfile() ) zu verwenden, um Daten direkt zwischen einem Shared-Memory-Objekt und einer Datei hin- und herzuschieben?

Funktionen wie sendfile() und fcopyfile() können alle mechanistischen Notwendigkeiten, die solche Datenübertragungen unterstützen, vollständig ausführen, ohne kernel-space zu verlassen - beim Aufruf dieser Funktionen übergeben Sie zwei offene Deskriptoren, eine Quelle und ein Ziel, und Sie nehmen es von dort.

Andere Mittel zum Kopieren von Daten erfordern unweigerlich ein manuelles Manövrieren über die Grenze zwischen Kernel-Space und User-Space; Solche Kontext-Schalter sind von Natur aus ziemlich kostspielig, was die Leistung angeht.

Ich kann nichts definitives zum Thema finden, einen Shared-Memory-Deskriptor als Argument zu verwenden: keine Artikel für oder gegen die Praxis; nichts in den jeweiligen man -Seiten; keine Tweets, in denen sendfile() -ing shared-memory-Deskriptoren öffentlich berücksichtigt werden; & amp; c ... Aber ich denke, ich sollte in der Lage sein, so etwas zu tun:

%Vor%

... Ist das fehlgeleitet oder eine gültige Technik?

Und wenn letzteres, kann man die Größe der im Speicher freigegebenen Karte vor dem Kopieren der Daten anpassen?

EDIT: Ich entwickle das Projekt, zu dem sich diese Anfrage bezieht, auf macOS 10.12.4; Ich bin bestrebt, dass es unter Linux mit eventueller FreeBSD-Interoperabilität funktioniert.

    
fish2000 13.05.2017, 22:56
quelle

1 Antwort

3

Das Kopieren von Daten zwischen zwei "Dingen", die im Speicher abgebildet sind - wie im obigen Beispiel - erfordert in der Tat das Kopieren von Dingen vom Kernel zum Benutzer und dann zurück. Und nein, Sie können sendfile (2) Systemaufruf nicht wirklich verwenden, um an einen Dateideskriptor zu senden, fürchte ich.

Aber Sie sollten es so machen können:

  1. Erzeuge das Shared-Memory-Objekt (oder eine Datei, wirklich; aufgrund des zweiten Schritts wird es sowieso im Speicher geteilt)
  2. Ordne es im Speicher zu, mit MAP_SHARED; Sie erhalten einen Zeiger
  3. Öffnen Sie die Zieldatei
  4. write (destination_fd, source_pointer, source_length)

In diesem Fall muss der Schreibsyscall die Daten nicht in Ihren Prozess kopieren. Nicht sicher, was das tatsächliche Leistungsmerkmal sein wird. Intelligente Verwendung von madvise (2) könnte helfen.

    
Edward Tomasz Napierala 02.06.2017, 14:17
quelle