multithreading - 将对象参数传递给宏

标签 multithreading macros lisp common-lisp ccl

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

我希望使用 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-filedestructuring-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/

相关文章:

lisp - CLISP - 反转一个简单列表

c# - WebApi 返回 HTTP 响应后是否可以执行代码?

c++ - 危险指针如何在不使用锁的情况下安全地回收并发数据结构中的内存?

java - 如何等待数据缓存更新,同时不影响其他缓存调用

macros - 宏应该有副作用吗?

printing - 执行方案代码

linux - 在 Linux 中对客户端断开连接使用react

c - 为调用 printf 的宏添加前缀

动态使用不同定义的 C 宏

lisp - 从 .NET/C# 调用 LISP 或 SCHEME