常见的lisp从FIFO读取超时

时间:2016-12-23 18:11:38

标签: common-lisp fifo sbcl

所以我有一些像

这样的代码
(let ((file (open cur-fifo :if-does-not-exist :create)))
  (format t "~A~%" (read-line file nil))
  (close file))

据我所知,工作正常,但如果没有数据写入cur-fifo,这将无限期地阻止。如果在~0.1秒左右无法读取数据,我希望读取超时并返回NIL。

在64位Gentoo Linux上运行SBCL 1.1.18

1 个答案:

答案 0 :(得分:3)

FIFO model

当您open fifo特殊设备(用于阅读)时,系统会调用阻止,除非

  • fifo已经被(另一个)写入OR的过程打开了
  • 您将O_ASYNC传递给open(2) - 您可能无法在实施中执行此操作,除非您使用的是低级别包sb-posix

当您成功打开 fifo时,您的read(2)调用将阻止,直到您的对方(打开fifo进行写入,这可能是相同的lisp进程)写入< / em>那里的东西。

Common Lisp

您要找的是listen(另见with-open-file):

(with-open-file (fifo "my-fifo" :if-does-not-exist :create)
  (when (or (listen fifo)
            (progn (sleep 0.1)
                   (listen fifo)))
    (format t "Read [~A]~%" (read-line fifo))))

调试

请注意,并非所有CL供应商都同样支持特殊设备处理。 如果以上操作不起作用,请使用REPL进行一些实验:打开fifo,查看listen返回的内容,在那里写一些内容,查看现在listen报告的内容,&amp; c。

如果listen仍然返回nil,即使您已经在管道中写入内容,这可能意味着您的CL无法将该文件识别为特殊设备。您可能必须将一些特定于实现的参数传递给open,例如:buffering nil或其他(尝试(describe 'open))。