1

我正在尝试创建一个使用let*. 当我尝试运行它时,子进程处于 [reset] 状态。如果我使用解决方法并使用let,则线程以 [active] 开始,一切正常。

我对这种行为感到困惑,并希望得到解释。

(defparameter *g* 1)
(defparameter *res-list* nil)

(defun tester ()
  (let ((res *g*))
    (push res *res-list*)))

CL-USER> (ccl:process-run-function "test" 'tester)
#<PROCESS test(4856) [Active] #x3020036E30AD>
CL-USER> *res-list*
(1)

到目前为止一切正常。但是如果我将 let 更改为 let*,我会得到一个 [reset] 状态,但是子线程中的代码会被执行。

(defun tester ()
  (let* ((res *g*))
    (push res *res-list*)))

CL-USER> (ccl:process-run-function "test" 'tester)
#<PROCESS test(4862) [Reset] #x3020036BCF2D>
CL-USER> *res-list*
(1 1)

如果有人能给我指出一个可以解释不同状态的资源,我也会很感激。

谢谢。

4

1 回答 1

1

不同的结果不是因为letlet*。进程可以处于不同的状态,并且您只是看到不同的结果,这取决于您捕获进程以打印它的时间。当我在命令行运行您的代码时,我得到的主要是“重置”,但也有一些“疲惫”和“死机”。

$ ccl64 
Welcome to Clozure Common Lisp Version 1.7-r14925M  (LinuxX8664)!
? (defparameter *g* 1)
*G*
? (defparameter *res-list* nil)
*RES-LIST*
? (defun tester ()
    (let ((res *g*))
      (push res *res-list*)))
TESTER
? (ccl:process-run-function "test" 'tester)
#<PROCESS test(2) [Exhausted] #x30200058FDBD>
? (ccl:process-run-function "test" 'tester)
#<PROCESS test(3) [Reset] #x30200058CB3D>
? (ccl:process-run-function "test" 'tester)
#<PROCESS test(4) [Reset] #x30200058AB3D>
? (ccl:process-run-function "test" 'tester)
#<PROCESS test(7) [Dead] #x302000584B3D>
? (ccl:process-run-function "test" 'tester)
#<PROCESS test(8) [Reset] #x302000582B3D>

据我所知,该手册并没有详细说明这些不同的状态,但它确实有这个,这应该足以让您深入了解手册的其他部分:

7.3.2. 截至 2003 年 8 月:

  • 目前尚不清楚暴露 PROCESS-SUSPEND/PROCESS-RESUME 是否是一个好主意:不清楚它们是否提供了获胜的方式,很明显它们提供了失败的方式。

  • 传统上,可以重置和启用“已用尽”的进程。(这里使用的术语“用尽”表示进程的初始函数已经运行并返回,并且底层本地线程已被释放。)PROCESS-RESET 的主要用途之一是“回收”线程;启用一个耗尽的进程涉及创建一个新的本机线程(以及堆栈和同步对象和......),这是这种回收方案试图避免的那种开销。可能值得尝试收紧并声明将 PROCESS-ENABLE 应用于耗尽的线程是错误的(并使 PROCESS-ENABLE 检测到此错误。)

  • 当不是由 Clozure CL 创建的本机线程第一次调用 lisp 时,会创建一个“外部进程”,并且该进程被赋予其自己的一组初始绑定,并设置为看起来更像是由 MAKE 创建的进程-过程。外部进程的生命周期肯定不同于 lisp 创建的生命周期:重置/预设/启用外部进程是没有意义的,并且应该检测到执行这些操作的尝试并将其视为错误。

于 2014-03-12T16:49:52.177 回答