(普通)lisp中的Unix信号处理

and*_*rew 11 lisp signals common-lisp sigint ccl

我已经对这个问题进行了一些研究,结果显而易见.在Common Lisp中似乎存在依赖于实现的Unix信号处理方式,但是是否有一个包提供了交叉实现的信号处理方式?

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

我也没有完全嫁给使用SIGINT(尽管它是理想的).如果需要,我可以使用另一个信号.

如果这将是混乱的,有没有人有任何其他建议优雅地从应用程序外部关闭lisp应用程序?我有一个想法是创建一个应用程序监视的文件,如果它检测到文件,它会关闭......但是有点hacky.

谢谢!

and*_*rew 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))
Run Code Online (Sandbox Code Playgroud)

请注意,根据我的理解,回调体内的任何内容都必须简短而甜蜜!没有冗长的处理.在链接的文章,宏实际上只是用于处理信号,这是矫枉过正,我的目的,因为我刚刚从设置全局变量创建一个单独的线程nilt和返回.

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


krz*_*z00 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)))
Run Code Online (Sandbox Code Playgroud)

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


cor*_*ump 5

这是一个迟到的答案,但对于其他任何寻找此问题的人,请看一下Quicklisp上提供的琐碎信号.这是基于CFFI.

(signal-handler-bind ((:int  (lambda (signo)
                               (declare (ignorable signo))
                               ...handler...)))
  ...body...)
Run Code Online (Sandbox Code Playgroud)