Common lisp 从 FIFO 读取超时
Common lisp read from FIFO with timeout
所以我有一些代码像
(let ((file (open cur-fifo :if-does-not-exist :create)))
(format t "~A~%" (read-line file nil))
(close file))
据我所知,这可以正常工作,但如果没有数据写入 cur-fifo,这将无限期阻塞。如果在 ~0.1 秒左右无法读取数据,我希望读取超时并且 return NIL。
运行 在 SBCL 1.1.18 上,在 64 位 Gentoo 上 Linux
FIFO model
当你open
一个fifo
特殊设备(用于读取)时,系统调用阻塞除非
- fifo 已经被(另一个)进程打开用于写入 OR
- 您将
O_ASYNC
传递给 open(2)
- 除非您使用低级包 sb-posix
,否则您可能无法在实施中执行此操作
当你成功打开 fifo 时,你的 read(2)
调用将阻塞直到你的交易对手(打开 fifo 进行写入,这可能是同一个 lisp 进程) 在那里写一些东西。
普通 Lisp
你要找的是listen
(see also 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
returns,在那里写点东西,看看 listen
现在报告了什么, &c.
如果 listen
仍然 returns nil
即使您已经在管道中写入了一些内容,这可能意味着您的 CL 无法将该文件识别为特殊设备。您可能必须将一些特定于实现的参数传递给 open
,例如 :buffering nil
或其他东西(尝试 (describe 'open)
)。
所以我有一些代码像
(let ((file (open cur-fifo :if-does-not-exist :create)))
(format t "~A~%" (read-line file nil))
(close file))
据我所知,这可以正常工作,但如果没有数据写入 cur-fifo,这将无限期阻塞。如果在 ~0.1 秒左右无法读取数据,我希望读取超时并且 return NIL。
运行 在 SBCL 1.1.18 上,在 64 位 Gentoo 上 Linux
FIFO model
当你open
一个fifo
特殊设备(用于读取)时,系统调用阻塞除非
- fifo 已经被(另一个)进程打开用于写入 OR
- 您将
O_ASYNC
传递给open(2)
- 除非您使用低级包sb-posix
,否则您可能无法在实施中执行此操作
当你成功打开 fifo 时,你的 read(2)
调用将阻塞直到你的交易对手(打开 fifo 进行写入,这可能是同一个 lisp 进程) 在那里写一些东西。
普通 Lisp
你要找的是listen
(see also 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
returns,在那里写点东西,看看 listen
现在报告了什么, &c.
如果 listen
仍然 returns nil
即使您已经在管道中写入了一些内容,这可能意味着您的 CL 无法将该文件识别为特殊设备。您可能必须将一些特定于实现的参数传递给 open
,例如 :buffering nil
或其他东西(尝试 (describe 'open)
)。