lisp中的非阻塞输入

时间:2011-06-25 22:28:59

标签: lisp common-lisp slime

我有运行很长一段时间的程序,我想打断它但不能用ctrl-c ctrl-c打断它。我也不希望系统每隔一段时间等待一次击键。相反,如果我按下一个键,我希望它包装好并退出。我找到了listenread-char-no-hang,但我无法让它正常工作。这是我试图做的事情

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

显然,就找到key = -presses而言,这对于Xanax而言并不是一个懒惰。我做错了什么?

2 个答案:

答案 0 :(得分:1)

我相信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*

答案 1 :(得分:0)

我使用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并使用M-x slime-list-threads来停止先前在lisp映像中启动的作业。