0

将对象参数传递给宏时遇到错误。我必须引用这个论点,把它放在一个列表中,还是不引用它?

我希望使用 Clozure Common Lisp 生成和并行运行多个进程,使用读写锁来控制数据输出到另一个进程。With-write-lock 是一个宏,它等待给定的锁可用于写访问,然后在持有锁的情况下执行其主体。但是,无论我如何尝试将锁传递给 with-write-lock,我都会遇到错误。我认为我遇到了麻烦,因为我不明白如何将锁定对象传递给 with-write-lock 宏。如果我将锁绑定到一个符号,我会得到解构错误:

(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.

执行时:(:INTERNAL CCL::NX1-COMPILE-LAMBDA),在进程 Listener(4)。

但是如果我将调用 make-read-write-lock 作为 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

错误:未绑定变量:MAKE-READ-WRITE-LOCK 执行时:#,正在处理 Listener(4)。

我失败是因为我误解了如何将对象传递给宏,还是因为写锁更特别的原因而出错?

这是 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)))))))
4

1 回答 1

3

该宏的 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-filedestructuring-bind

(with-open-file ("path/to/file" :open :args)
  .... body ...)

(destructuring-bind (one two three) '(1 2 3)
  .... body forms ...)
于 2014-01-09T21:13:12.337 回答