2016-12-23 2 views
0

Поэтому у меня есть некоторый код, какCommon Lisp читать FIFO с тайм-аута

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

который, насколько я могу сказать отлично работает, за исключением того, что это будет блокировать на неопределенный срок, если данные не были записаны в текущ-ФИФО. Я хочу, чтобы чтение было тайм-аутом и возвращало NIL, если никакие данные не могли быть прочитаны через ~ 0,1 секунды или около того.

Бег на SBCL 1.1.18, на 64-битной Gentoo Linux

ответ

3

FIFO model

Когда вы не open а fifo специальное устройство (для чтения), системный вызов блоки если либо

  • fifo уже открыт (другим) процессом для записи ИЛИ
  • вы проходите O_ASYNC к open(2) - которые вы не могли бы сделать в вашей реализации, если не использовать пакет Низкого уровня sb-posix

Когда вы успешно открытие ФИФО, ваш read(2) вызова не будет блокировать до вашего контрагента (что открыто fifo для записи, который может быть тем же самым процессом lisp) пишет что-то там.

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

Debugging

Пожалуйста, обратите внимание, что специальная обработка устройства не обязательно одинаково хорошо поддерживается всеми CL поставщики. Если выше не работает, сделайте несколько экспериментов с REPL: откройте fifo, посмотрите, что возвращает listen, напишите что-нибудь там, посмотрите, что listen сообщает сейчас, & c.

Если listen все еще возвращает nil, хотя вы уже что-то написали в трубе, это может означать, что ваш CL не распознает файл как специальное устройство. Возможно, вам придется передать некоторые аргументы, специфичные для реализации, до open, например, :buffering nil или что-то (попробуйте (describe 'open)).

+0

Не работает, проблема сохраняется. –

+0

В случае, если это не было очевидно из кода, файл, который я читаю, является FIFO (т. Е. Именованным каналом, созданным с помощью 'mkfifo') –

+0

@KahrKunne: см. Мои правки. отредактируйте свой вопрос, чтобы добавить сведения о поставщике. – sds