2014-12-12 10 views
7

Dokładnie tak, jak mówi to pytanie. Chcę używać pamięci współdzielonej do komunikacji między dwoma procesami seplenienia. Jakieś wskazówki, jak to zrobić?W jaki sposób mogę odwzorować pliki tmpfs na pamięć w sbcl?

widzę kilka tutoriali na ten sposób w clozure na: -

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

Czy ktoś może wskazać mi podobny biblioteki to zrobić z SBCL?

+0

Dzięki za odpowiedzi! Oba wydają się rozwiązywać mój problem, więc zamierzam je wypróbować i zaakceptować ten, z którego korzystam. – owagh

Odpowiedz

6

Istnieje funkcja mmap niskiego poziomu w pakiecie z 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 

Musisz użyć wyraźne arytmetyki adresu, aby go używać, jak w C.

9

dla przenośnego realizacji, może chcesz użyj biblioteki osicat, która zapewnia opakowanie CFFI dla wielu wywołań POSIX w pakiecie osicat-posix.

Istnieje bardzo ładny i krótki artykuł z kodem do używania go pod numerem http://wandrian.net/2012-04-07-1352-mmap-files-in-lisp.html (autor: Nicolas Martyanoff).

Aby zachować, że ja przeważnie cytują stamtąd:

Mapowanie pliku odbywa się poprzez otwarcie go z osicat-posix:open, czytając jego wielkości z fstat, następnie wywołanie mmap. Po zmapowaniu pliku możemy zamknąć deskryptor pliku, nie jest już potrzebny.

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

Funkcja mmap plik zwraca dwie wartości: adres mapowania pamięci i jej wielkość.

Odwzorowanie tego fragmentu pamięci odbywa się za pomocą osicat-posix:munmap.

Dodajmy makro bezpiecznie Mapa i pliki 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)))))) 

To makro mmap s dany plik i wiąże obie zmienne podane na jego adres i i wielkości. Następnie można obliczyć wskaźniki adresu za pomocą cffi:inc-pointer i uzyskać dostęp do zawartości pliku za pomocą cffi:mem-aref. Możesz zbudować wokół siebie własne opakowania, aby przedstawić format pliku (np. Zwykły tekst w UTF-8).

(w porównaniu do delegowania połączonego powyżej, usunąłem owijanie osicat-posix:munmap do innej funkcji dokładnie taki sam podpis i skutku, ponieważ wydawało mi się zbędne.)

+0

Uwaga: 'osicat-posix: mmap' NIE obsługuje systemu Windows. W systemie Windows jest 'CreateFileMapping', sprawdź plik kodu źródłowego SBCL' src/code/win32.lisp'. – muyinliu

Powiązane problemy