如何替换Common Lisp中正在运行的功能? [英] How to replace a running function in Common Lisp?
问题描述
假设我们使用SBCL的#'save-lisp-die来创建服务器应用程序App1,该服务器应用程序效果很好.现在我们要用新版本替换功能#'func1而不停止App1.我们如何在Common Lisp中做到这一点?
Suppose we use SBCL's #'save-lisp-and-die to create an server applicatioon App1, which works very well. Now we want to replace a function #'func1 with a new version without stopping App1. How can we do it in Common Lisp ?
任何建议都值得赞赏!
推荐答案
您需要加载新的函数定义.然后新功能将立即可用;代码将调用新加载的函数.
You need to load the new function definition. Then new function will be available immediately; code will call newly loaded function.
可以通过多种方式加载新函数定义:
New function definition may be loaded in many ways:
-
(load (compile-file "file.lisp"))
,其中file.lisp
是函数的源代码 -
(load "file.fasl")
其中file.fasl
是已编译的源代码 -
(eval (defun ...))
(load (compile-file "file.lisp"))
wherefile.lisp
is a source code for function(load "file.fasl")
wherefile.fasl
is compiled source code(eval (defun ...))
当然,有例外和复杂之处:
Of course, there are exceptions and complications:
- 这不会替代先前功能的已经运行的调用;例如,无法以这种方式更改无限事件循环-它必须支持某种停止和调用新函数.但是,这种长时间运行的功能很少见.可以通过使用递归而不是循环来解决此问题(但并非所有编译器都进行尾调用优化).
- 如果您在某处抓取了一个指向函数的指针(例如,按
(function FOO)
,其中FOO
是函数的名称),它将保留其旧值.为避免这种情况,请使用符号代替函数指针(符号可以funcall
). - 函数的代码需要进行垃圾回收.您应注意不要留下对函数旧版本的引用.另外,如果不需要某些功能,则不要忘记
fmakunbound
它们的符号. - 如果该函数是在编译时使用的,则所有受影响的代码也都应重新加载
- 如果您进行了高级优化(默认情况下未启用),则编译器可能会将函数内联到其他函数中. CLHS会区分重新定义功能成为未定义行为"的情况.
- This will not replace already running calls of previous functions; for example, an infinite event loop can not be changed this way - it will have to support some kind of stopping and calling a new function. However, such long-running functions are rare. It can be worked around by using recursion instead of looping (but not all compilers do tail-call optimization).
- If you somewhere grabbed a pointer to function (for example, by
(function FOO)
whereFOO
is the name of a function), it will retain its old value. To avoid this, use symbols instead of function pointers (symbols arefuncall
able). - The code of a function is a subject to garbage collection. You should be careful not to leave references to old versions of a function lying around. Also, if some functions become not needed, you should not forget to
fmakunbound
their symbols. - If the function was used at compile time, all of the affected code should also be reloaded
- If you had high levels of optimization (which is not by default), compiler might have inlined the function into others. CLHS discriminates the cases when redefining a function becomes «undefined behavior».
但是实际上,代码重装在大多数Common Lisp实现中都可以很好地工作.
But in practice, code reloading works well in most Common Lisp implementations.
这篇关于如何替换Common Lisp中正在运行的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!