我在这个主题上做了一些研究,但发现了一些空白。在Common Lisp中似乎有一些依赖于实现的方式来处理Unix信号,但是有没有一个包可以提供一种跨实现的方式来处理信号呢?
我主要想监听SIGINT,并在我的应用程序中优雅地关闭。我在上面提到的linux...like上使用Clozure CL1.7,这对于一个包来说是很棒的,但是如果我必须求助于特定于实现的代码,那也没问题。
我也不完全喜欢使用SIGINT (尽管它是理想的)。如果需要,我可以使用另一个信号。
如果这将是混乱的,有没有人有任何其他建议,以优雅地关闭一个lisp应用程序从应用程序之外?我的一个想法是创建一个应用程序监控的文件,如果它检测到这个文件,它就会关闭hacky的down...kind。
谢谢!
发布于 2012-03-31 09:19:33
我也找不到用于信号处理的通用库。但是,对于大多数Lisp实现,Slime实现了“创建自定义SIGINT处理程序”。通过查看该代码的CCL用例,我发现了ccl:*break-hook*。文档中没有介绍ccl:*break-hook*,但是引入它的提交位于here。
这个简单的示例代码可以在我的系统(CCL1.8,linux x86)上运行:
(setf ccl:*break-hook*
(lambda (cond hook)
(declare (ignore cond hook))
(format t "Cleaning up ...")
(ccl:quit)))在将此代码输入非粘滞REPL后,发送SIGINT将导致程序打印"Cleaning up ...“然后退出。
发布于 2012-05-04 10:54:24
尽管出于无知,我最初对戴姆罗德关于使用CFFI的评论(问题下的第一个评论)持怀疑态度,但我又看了看,发现了http://clozure.com/pipermail/openmcl-devel/2010-July/011675.html。我对它进行了修改,以使用CFFI,并确认它在linux上的SBCL/CCL/clisp (可能是其他)上工作得很好:
(defmacro set-signal-handler (signo &body body)
(let ((handler (gensym "HANDLER")))
`(progn
(cffi:defcallback ,handler :void ((signo :int))
(declare (ignore signo))
,@body)
(cffi:foreign-funcall "signal" :int ,signo :pointer (cffi:callback ,handler)))))
(set-signal-handler 2
(format t "Quitting lol!!!11~%")
;; fictional function that lets the app know to quit cleanly (don't quit from callback)
(signal-app-to-quit))请注意,据我所知,回调主体中的任何内容都必须简短而甜蜜!没有冗长的处理。在链接的文章中,宏实际上创建了一个单独的线程来处理信号,这对于我的目的来说是多余的,因为我只是将一个全局变量从nil设置为t并返回。
无论如何,希望这对其他人有帮助!
发布于 2015-05-29 15:16:23
这是一个迟来的答案,但是对于其他正在搜索这个问题的人来说,可以看看Quicklisp上的。这是基于CFFI的。
示例
(signal-handler-bind ((:int (lambda (signo)
(declare (ignorable signo))
...handler...)))
...body...)https://stackoverflow.com/questions/9950680
复制相似问题