我在将对象参数传递给宏时遇到错误。我必须引用该论点,将其放入列表中,还是不引用它?
我希望使用 Clozure Common Lisp 生成并并行运行多个进程,使用读写锁控制数据输出到另一个进程。 With-write-lock 是一个宏,它等待给定的锁可用于写访问,然后在持有锁的情况下执行其主体。但是,无论我如何尝试将锁传递给 with-write-lock,我都会出错。我认为我遇到了麻烦,因为我不明白如何将锁定对象传递给 with-write-lock 宏。如果我将锁绑定(bind)到一个符号,我会得到解构错误:
(let ((l (make-read-write-lock)))
(with-write-lock l (1+ 1)))
==>
> Error: L can't be destructured against the lambda list (LOCK), because it is not a proper list.
While executing: (:INTERNAL CCL::NX1-COMPILE-LAMBDA), in process Listener(4).
但是如果我将对 make-read-write-lock 的调用作为锁定参数传递给 with-write-lock,那么我会得到一个未声明的自由变量错误:
(with-write-lock (make-read-write-lock) (1+ 1))
==>
;Compiler warnings for "/Users/frank/Documents/Lisp/threaded/act-parallel.lisp" :
;In an anonymous lambda form at position 18: Undeclared free variable MAKE-READ-WRITE-LOCK
Error: Unbound variable: MAKE-READ-WRITE-LOCK While executing: #, in process Listener(4).
我失败是因为我误解了如何将对象传递给宏,还是因为 with-write-lock 更特殊的原因而出错?
这是 Clozure Common Lisp (macros.lisp) 附带的 with-write-lock 宏:
(defmacro with-write-lock ((lock) &body body)
(let* ((locked (gensym))
(p (gensym)))
`(with-lock-context
(let* ((,locked (make-lock-acquisition))
(,p ,lock))
(declare (dynamic-extent ,locked))
(unwind-protect
(progn
(write-lock-rwlock ,p ,locked)
,@body)
(when (lock-acquisition.status ,locked) (unlock-rwlock ,p)))))))
最佳答案
该宏的 lambda 列表正在解构其参数。
((lock) &body body)
意味着它希望第一个参数是一个列表,其中包含锁,然后是主体形式。这是 CL 中一个非常标准的宏参数列表,您可以像这样使用它:
(with-write-lock (lock)
..... body forms ....)
所以你的例子是
(let ((l (make-read-write-lock)))
(with-write-lock (l) (1+ 1)))
和:
(with-write-lock ((make-read-write-lock)) (1+ 1))
分别。注意第一个参数周围的额外括号。
对于类似的宏,请参阅 with-open-file
或 destructuring-bind
(with-open-file ("path/to/file" :open :args)
.... body ...)
(destructuring-bind (one two three) '(1 2 3)
.... body forms ...)
关于multithreading - 将对象参数传递给宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20981241/