2014-12-12 13 views
7

Esattamente come dice la domanda. Voglio usare la memoria condivisa per comunicare tra due processi lisp. Qualche suggerimento su come farlo?Come posso memorizzare i file tmpfs nella memoria in sbcl?

posso vedere alcuni tutorial a fare questo in Clozure a: -

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

Qualcuno mi può puntare a una libreria simile a che fare questo con SBCL?

+0

Grazie per le risposte! Entrambi sembrano risolvere il mio problema, quindi li proverò e accetterò quello che uso. – owagh

risposta

6

C'è basso livello funzione mmap bundle con SBCL:

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 

Devi usare aritmetica degli indirizzi espliciti di usarlo, come in C.

9

Per un'implementazione portatile, si potrebbe desiderare di utilizzare la libreria osicat, che fornisce un wrapper CFFI per molte chiamate POSIX nel pacchetto osicat-posix.

C'è un articolo molto bello e breve con il codice per utilizzarlo a http://wandrian.net/2012-04-07-1352-mmap-files-in-lisp.html (di Nicolas Martyanoff).

di conservare in voi, io per lo cito da lì:

Mappatura di un file è fatto aprendolo con osicat-posix:open, leggendo la sua dimensione con fstat, quindi chiamando mmap. Una volta che il file è stato mappato, possiamo chiudere il descrittore del file, non è più necessario.

(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)))) 

La funzione mmap file restituisce due valori: l'indirizzo della mappatura della memoria e la sua dimensione.

L'eliminazione di questo blocco di memoria viene effettuata con osicat-posix:munmap.

Aggiungiamo una macro per mappare in modo sicuro e file unmap:

(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)))))) 

Questa macro mmap s il file data e collega i due dati variabili al suo indirizzo e e dimensione. È quindi possibile calcolare i puntatori di indirizzo con cffi:inc-pointer e accedere ai contenuti del file con cffi:mem-aref. Potresti voler costruire i tuoi wrapper attorno a questo per rappresentare il formato del tuo file (per esempio testo normale in UTF-8).

(Rispetto al distacco linkato sopra, ho tolto l'involucro di osicat-posix:munmap in un'altra funzione della esattamente la stessa firma e l'effetto, perché mi sembrava superfluo per me.)

+0

Nota: 'osicat-posix: mmap' NON supporta Windows. C'è 'CreateFileMapping' su Windows, si prega di controllare il file del codice sorgente SBCL' src/code/win32.lisp'. – muyinliu

Problemi correlati