12

我已经对这个主题进行了一些研究,并且出现了空白。在 Common Lisp 中似乎有一些依赖于实现的方式来处理 Unix 信号,但是是否有一个包可以提供一种交叉实现的信号处理方式?

我主要想收听 SIGINT 并在我的应用程序中正常关闭。我在 linux 上使用 Clozure CL 1.7 ......就像提到的那样,这对于一个包来说会很棒,但如果我不得不求助于特定于实现的代码,那很好。

我也没有完全同意使用 SIGINT(尽管它很理想)。如果需要,我可以使用另一个信号。

如果这会变得一团糟,是否有人对从应用程序外部优雅地关闭 lisp 应用程序有任何其他建议?我的一个想法是创建一个应用程序监视的文件,如果它检测到该文件,它就会关闭......不过有点hacky。

谢谢!

4

4 回答 4

8

尽管出于无知,我最初对 Daimrod 关于使用 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))

请注意,据我了解,回调正文中的任何内容都必须简短而甜蜜!无需冗长的处理。在链接的文章中,宏实际上创建了一个单独的线程来处理信号,这对我的目的来说是多余的,因为我只是设置一个全局变量 from niltot并返回。

无论如何,希望这对其他人有帮助!

于 2012-05-04T02:54:23.520 回答
7

我也找不到用于信号处理的通用库。然而,SlimeSIGINT为大多数 Lisp 实现实现了“创建自定义处理程序”。通过查看该代码的 CCL 案例,我发现ccl:*break-hook*. ccl:*break-hook*不在文档中,但引入它的提交位于此处

这个简单的示例代码适用于我的系统(CCL 1.8,linux x86):

(setf ccl:*break-hook* 
  (lambda (cond hook)                              
    (declare (ignore cond hook))
    (format t "Cleaning up ...")
    (ccl:quit)))

将此代码输入非 Slime REPL 后,发送SIGINT将导致程序打印“正在清理...”并退出。

于 2012-03-31T01:19:32.537 回答
6

这是一个较晚的答案,但对于其他搜索此问题的人,请查看 Quicklisp 上提供的trivial-signal 。这是基于 CFFI。

例子

(signal-handler-bind ((:int  (lambda (signo)
                               (declare (ignorable signo))
                               ...handler...)))
  ...body...)
于 2015-05-29T07:16:23.293 回答
1

如果使用 SBCL,则无法更改信号掩码而不导致 SBCL 崩溃。向 nyef 询问有关如何修复 SBCL 的提示...

于 2015-08-24T17:50:35.183 回答