我如何在sbcl中内存映射tmpfs文件?

owa*_*agh 7 sbcl common-lisp shared-memory memory-mapped-files

正如问题所说的那样.我想使用共享内存在两个lisp进程之间进行通信.有关如何做到这一点的任何指示?

我可以在clozure中看到一些关于这样做的教程: -

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

有人能指点我用类似的库来用sbcl做这个吗?

Sva*_*nte 9

对于可移植实现,您可能希望使用该osicat库,该库为osicat-posix包中的许多POSIX调用提供CFFI包装.

http://wandrian.net/2012-04-07-1352-mmap-files-in-lisp.html(由Nicolas Martyanoff撰写)中有一篇非常好的短篇文章,其中包含使用它的代码.

为了保留这一点,我主要从那里引用:

映射文件是通过打开文件osicat-posix:open,读取文件大小fstat,然后调用来完成的mmap.一旦文件被映射,我们可以关闭文件描述符,不再需要它了.

(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))))
Run Code Online (Sandbox Code Playgroud)

mmap-file函数返回两个值:内存映射的地址及其大小.

取消映射这块内存就完成了osicat-posix:munmap.

让我们添加一个宏来安全地映射和取消映射文件:

(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))))))
Run Code Online (Sandbox Code Playgroud)

此宏mmap是给定文件,并将两个给定变量绑定到其地址和大小.然后,您可以使用计算地址指针cffi:inc-pointer并访问文件内容cffi:mem-aref.您可能希望围绕此构建自己的包装器来表示文件的格式(例如,UTF-8中的纯文本).

(与上面链接的帖子相比,我删除了包含osicat-posix:munmap到具有完全相同签名和效果的另一个函数,因为它对我来说似乎是多余的.)


mon*_*oid 6

有sbcl捆绑的低级mmap函数:

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
Run Code Online (Sandbox Code Playgroud)

您必须使用显式地址算术来使用它,如在C.