lisp中的非阻塞输入

lisp中的非阻塞输入,lisp,common-lisp,slime,Lisp,Common Lisp,Slime,我有一个长时间运行的程序,我想中断它,但不能用ctrl-c ctrl-c。我也不希望系统每隔一段时间就等待一次击键。相反,如果我真的按了一个键,我希望它把东西包起来并退出。我发现listen和read char no hang但我无法让它正常工作。这就是我想做的 (let ((f nil)) (loop while (not f) do (if (listen) (setf f t))))) 显然,在查找key=-press方面,这比Xanax上的懒汉做的要少。我做

我有一个长时间运行的程序,我想中断它,但不能用ctrl-c ctrl-c。我也不希望系统每隔一段时间就等待一次击键。相反,如果我真的按了一个键,我希望它把东西包起来并退出。我发现
listen
read char no hang
但我无法让它正常工作。这就是我想做的

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

显然,在查找key=-press方面,这比Xanax上的懒汉做的要少。我做错了什么?我相信CCL有多线程。您可以尝试在后台生成一个工作线程,让一个控制线程执行阻塞读取,然后通过一个特殊变量进行通信。以下是Lispworks中的工作,我没有CCL可用。您必须将mp:process run函数转换为CCL用于生成线程的任何函数:

(定义参数*f*nil)
(defun cmd循环()
(setf*f*nil)
(mp:进程运行函数“work”(#“do-work”);生成工作者
(读取字符*终端io*);阻止读取
(setf*f*t)
(不做工作)
(循环而非*f*)
做
(格式t“~a”*f*)
(完成输出)
(cmd循环)

我在这里做的一个大假设是CCL多线程与LW多线程的工作原理类似,因此两个线程都可以访问共享状态变量
*f*

我使用SLIM来实现这些功能。 我通常在远程计算机上启动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内的笔记本电脑上启动slime会话:

M-x slime-connect
localhost
4005
C-x C-f /ssh:remotehost:project/test.lisp
您必须设置TRAMP才能使其工作。 您还应该确保您有一个合理的ssh设置(如果您想远程工作)。 将其添加到/etc/ssh/ssh\u config。它将加快许多ssh连接的握手速度

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

然而,如果你只想让东西在你的本地机器上运行,一切都会容易得多。您可以重新连接SLIME并使用M-x SLIME列表线程来停止您在lisp映像中之前启动的作业。

哪个版本的lisp在哪里运行?很可能得到您想要的东西取决于实现,所以您使用的是哪种lisp?@bmargiles@Will Hartung-CCL在使用SLIME的Aquamacs上运行?您能再解释一下吗?您是否在关注与长时间运行的进程不同的线程中的按键?工作是否被分解成小块,并且是您正在轮询按键的同一个循环的一部分?在上面的示例中,
cmd循环
当然不是一个真正的循环。我保留了这个名字,因为根据我的经验,在现实世界中可能是这样,而且会做一些比戒烟更有趣的事情。