2014-12-12 18 views
7

Chính xác như câu hỏi nói. Tôi muốn sử dụng bộ nhớ chia sẻ để giao tiếp giữa hai quá trình lisp. Bất kỳ gợi ý về cách làm điều đó?Làm cách nào để nhớ tệp tmpfs bản đồ trong sbcl?

tôi có thể thấy một số hướng dẫn về việc này trong clozure tại địa chỉ: -

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

Ai đó có thể chỉ cho tôi một thư viện tương tự để làm điều này với sbcl?

+0

Cảm ơn câu trả lời! Cả hai dường như giải quyết vấn đề của tôi vì vậy tôi sẽ thử chúng ra và chấp nhận một trong những tôi kết thúc bằng cách sử dụng. – owagh

Trả lời

6

Có chức năng mmap ở mức độ thấp kèm với 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 

Bạn phải sử dụng arithmetics địa chỉ rõ ràng để sử dụng nó, như trong C.

9

Đối với việc thực hiện di động, bạn có thể muốn sử dụng thư viện osicat, cung cấp trình bao bọc CFFI cho nhiều cuộc gọi POSIX trong gói osicat-posix.

Có một bài viết rất hay và ngắn với mã để sử dụng nó tại http://wandrian.net/2012-04-07-1352-mmap-files-in-lisp.html (bởi Nicolas Martyanoff).

Để gìn giữ đó, tôi chủ yếu là trích dẫn từ đó:

Lập bản đồ một tập tin được thực hiện bằng cách mở nó với osicat-posix:open, đọc kích thước của nó với fstat, sau đó gọi mmap. Khi tệp đã được ánh xạ, chúng tôi có thể đóng bộ mô tả tệp, không cần thiết nữa.

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

Chức năng mmap-file trả về hai giá trị: địa chỉ của ánh xạ bộ nhớ và kích thước của nó.

Việc hủy ánh xạ đoạn bộ nhớ này được thực hiện với osicat-posix:munmap.

Hãy thêm một macro để ánh xạ một cách an toàn và các tập tin 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)))))) 

vĩ mô mmap s file cho này và liên kết hai biến cho địa chỉ và và kích thước của nó. Sau đó, bạn có thể tính toán con trỏ địa chỉ với cffi:inc-pointer và truy cập nội dung tệp với cffi:mem-aref. Bạn có thể muốn xây dựng các trình bao bọc riêng của mình xung quanh điều này để thể hiện định dạng tệp của bạn (ví dụ: văn bản thuần trong UTF-8).

(So với việc niêm yết liên kết ở trên, tôi loại bỏ các gói của osicat-posix:munmap vào một chức năng hoàn toàn giống chữ ký và có hiệu lực, vì nó có vẻ không cần thiết đối với tôi.)

+0

Lưu ý: 'osicat-posix: mmap' KHÔNG hỗ trợ Windows. Có 'CreateFileMapping' trên Windows, hãy kiểm tra tệp mã nguồn SBCL' src/code/win32.lisp'. – muyinliu

Các vấn đề liên quan