Неблокирующий ввод в lisp - PullRequest
4 голосов
/ 26 июня 2011

У меня есть программа, которая выполняется в течение длительного времени, и я хотел бы прервать ее, но не с помощью ctrl-c ctrl-c. Я также не хочу, чтобы система каждый раз ждала нажатия клавиш. Вместо этого, если я нажимаю клавишу, я хочу, чтобы она завернулась и вышла. Я нашел listen и read-char-no-hang, но не могу заставить его работать правильно. Вот что я пытался сделать

(let ((f nil))
  (loop while (not f) do
     (if (listen)
       (setf f t)))))

Очевидно, что это делает меньше, чем ленивец на Xanax, чтобы найти key = -press. Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 01 июля 2011

CCL имеет многопоточность, я полагаю. Вы можете попробовать порождать рабочий поток в фоновом режиме и иметь управляющий поток, выполняющий блокирующее чтение, а затем обменивающийся данными через специальную переменную. Следующие работы в Lispworks, у меня нет CCL. Вам нужно будет перевести mp: process-run-function к тому, что CCL использует для порождения потоков:

(defparameter *f* nil)
(defun cmd-loop ()
  (setf *f* nil)
  (mp:process-run-function "work" () #'do-work)  ; Spawn worker
  (read-char *terminal-io*)                      ; Blocking read
  (setf *f* t))
(defun do-work ()
  (loop while (not *f*)
        do 
          (format t "~a " *f*)
          (finish-output)))
(cmd-loop)

Большое предположение, которое я здесь делаю, заключается в том, что многопоточность CCL работает аналогично многопоточности LW, поэтому оба потока могут получить доступ к переменной общего состояния *f*.

0 голосов
/ 01 июля 2011

Я использую SLIME для этих вещей.Обычно я запускаю lisp на удаленном компьютере следующим образом:

whoplisp@laptop:~$ ssh -L4005:127.0.0.1:4005 remotecomputer
whoplisp@remotecomputer:~$ sbcl
(require :asdf)
(require :swank)
(setf swank:*dedicated-output-stream-port* nil)
(swank:create-server)

Затем я могу запустить слизистую сессию на ноутбуке из Emacs:

M-x slime-connect
localhost
4005
C-x C-f /ssh:remotehost:project/test.lisp

Вам нужно будет настроить TRAMPчтобы это работало.Вы также должны убедиться, что у вас есть разумные настройки ssh (если вы хотите работать удаленно).Добавьте это в / etc / ssh / ssh_config.Это ускорит рукопожатия для многих соединений ssh.

Host remotehost
  ControlMaster auto
  ControlPath /tmp/%r@%h:%p

Однако, если вы просто хотите, чтобы все работало на вашей локальной машине, все намного проще.Вы можете восстановить соединение с SLIME и использовать Mx slime-list-threads, чтобы остановить задания, которые вы начали ранее в образе lisp.

...