线程中的Lparallel软件包切换

时间:2019-04-01 02:34:01

标签: multithreading package common-lisp

使用Common Lisp的Lparallel库,可以通过调用(submit-task channel function)启动运行的并行线程。这将在新的并行线程中执行给定的功能。但是,该函数似乎总是在:cl-user程序包中运行,而不是在其中定义该程序包的情况下运行。我只是想知道为什么Lparallel是这样设计的。您可以通过在函数中包含(in-package :my-package)进行覆盖,但是这种可预测性是否有一些优势?

#-:lparallel
  (ql:quickload :lparallel)

(defpackage :test (:use :cl :lparallel))

(in-package :test)

(defun main ()
  (setf lparallel:*kernel* (lparallel:make-kernel 1))
  (print *package*)
  (let ((c (make-channel)))
    (submit-task c (lambda () (print *package*))))
  (lparallel:end-kernel))

给予:

* (load "d:\\test.lisp")
To load "lparallel":
  Load 1 ASDF system:
    lparallel
; Loading "lparallel"

T
* (in-package :test)
#<PACKAGE "TEST">
* (main)

#<PACKAGE "TEST">
#<PACKAGE "COMMON-LISP-USER">
(#<SB-THREAD:THREAD "lparallel kernel shutdown manager" FINISHED values: NIL {1005873953}>
 #<SB-THREAD:THREAD "lparallel" FINISHED values: NIL {10058735F3}>)

1 个答案:

答案 0 :(得分:3)

动态变量的默认行为是,线程之间仅共享全局环境中的绑定(即,不是动态重新绑定)。

*package*的值在运行时几乎无关紧要,除非进行read时(这在运行时不常见,并且无论如何您都明确绑定了*package*)。因此,没有理由偏离上述标准行为。

在代码(例如,函数)和作为*package*的值的包之间的连接在读取,编译或加载时也不存在。 *package*的唯一作用是实习,查找或打印符号时的默认程序包。