2014-12-12 11 views
7

Genau wie die Frage sagt. Ich möchte Shared Memory verwenden, um zwischen zwei Lisp-Prozessen zu kommunizieren. Irgendwelche Hinweise, wie man das macht?Wie speicher ich tmpfs-Dateien in sbcl?

Ich kann einige Tutorials siehe hierzu unter in Clozure tun: -

http://ccl.clozure.com/manual/chapter4.7.html

jemand mich auf eine ähnliche Bibliothek verweisen kann dies mit sbcl zu tun?

+0

Danke für die Antworten! Beide scheinen mein Problem zu lösen, also probiere ich sie aus und akzeptiere die, die ich am Ende benutze. – owagh

Antwort

6

Es gibt Low-Level-mmap Funktion mit sbcl gebündelt:

CL-USER> (apropos "MMAP") 
SB-POSIX:MMAP (fbound) 
; No value 
CL-USER> (describe 'sb-posix:mmap) 
SB-POSIX:MMAP 
[symbol] 

MMAP names a compiled function: 
Lambda-list: (ADDR LENGTH PROT FLAGS FD OFFSET) 
Derived type: (FUNCTION (T T T T T T) 
       (VALUES SYSTEM-AREA-POINTER &OPTIONAL)) 
Inline proclamation: INLINE (inline expansion available) 
Source file: SYS:CONTRIB;SB-POSIX;INTERFACE.LISP.NEWEST 
; No value 

Sie haben explizite Adresse arithmetics verwenden, um es zu verwenden, wie in C.

9

Für eine portable Implementierung, möchten Sie vielleicht Verwenden Sie die osicat-Bibliothek, die einen CFFI-Wrapper für viele POSIX-Aufrufe im osicat-posix-Paket bereitstellt.

Es gibt einen sehr schönen und kurzen Artikel mit Code für die Verwendung bei http://wandrian.net/2012-04-07-1352-mmap-files-in-lisp.html (von Nicolas Martyanoff).

Um das zu bewahren, ich meistens von dort zitieren:

eine Dateizuordnung durch Öffnen mit osicat-posix:open, das Lesen seiner Größe mit fstat, dann mmap Aufruf erfolgt. Sobald die Datei zugeordnet wurde, können wir den Dateideskriptor schließen, er wird nicht mehr benötigt.

(defun mmap-file (path) 
    (let ((fd (osicat-posix:open path (logior osicat-posix:o-rdonly)))) 
    (unwind-protect 
     (let* ((size (osicat-posix:stat-size (osicat-posix:fstat fd))) 
       (addr (osicat-posix:mmap (cffi:null-pointer) size 
             (logior osicat-posix:prot-read) 
             (logior osicat-posix:map-private) 
             fd 0))) 
      (values addr size)) 
     (osicat-posix:close fd)))) 

Die Mmap-Datei-Funktion gibt zwei Werte: die Adresse der Speicherzuordnung und seine Größe.

Die Zuordnung dieses Speicherbereichs erfolgt mit osicat-posix:munmap.

Lassen Sie uns ein Makro hinzufügen sicher abzubilden und unmap Dateien:

(defmacro with-mmapped-file ((file addr size) &body body) 
    (let ((original-addr (gensym "ADDR-")) 
     (original-size (gensym "SIZE-"))) 
    `(multiple-value-bind (,addr ,size) 
     (mmap-file ,file) 
     (let ((,original-addr ,addr) 
      (,original-size ,size)) 
     (unwind-protect 
       (progn ,@body) 
      (osicat-posix:munmap ,original-addr ,original-size)))))) 

Dieses Makro mmap s die angegebene Datei und die an seine Adresse zwei gegebenen Variablen bindet und und Größe. Sie können dann Adresszeiger mit cffi:inc-pointer berechnen und auf den Dateiinhalt mit cffi:mem-aref zugreifen. Vielleicht möchten Sie hier eigene Wrapper erstellen, um das Format Ihrer Datei darzustellen (z. B. Nur-Text in UTF-8).

(Im Vergleich zum Posting oben verbunden, entfernte ich die Verpackung von osicat-posix:munmap in einer anderen Funktion genau die gleichen Signatur und Wirkung, weil es überflüssig schien mir.)

+0

Hinweis: 'osicat-posix: mmap' unterstützt Windows NICHT. Es gibt 'CreateFileMapping' unter Windows, überprüfen Sie bitte die Quelldatei' src/code/win32.lisp'. – muyinliu