线程间消息传递的最佳风格?

Best style for message passing between threads?

我想异步调用各种线程中的函数,每个线程都有特定的 state,因此我将消息发送到给定线程并让该线程对这些消息进行操作。我想知道的是,这些消息最合理的样式是什么。我可以想到三种可能性。 (所有例子都排除了线程机制,以免复杂化。)

  1. 基于关键字的消息,根据状态和关键字进行调度。
(defclass state () ())

(defgeneric dispatch (object method args))

(defmethod dispatch ((object state) (method (eql :bazinga)) args)
  (destructuring-bind (arg1 arg2) args
    (format t "arg1 = ~a, arg2 = ~a~%" arg1 arg2)))

(let ((state (make-instance 'state))
      (msg '(:bazinga 10 20))) ; message example
  (dispatch state (car msg) (cdr msg))) 
  1. 基于函数的消息,根据状态进行调度。
(defclass state () ())

(defgeneric bazinga (object arg1 arg2))

(defmethod bazinga ((object state) arg1 arg2)
  (format t "arg1 = ~a, arg2 = ~a~%" arg1 arg2))

(let ((state (make-instance 'state))
      (msg (list #'bazinga 10 20))) ; message example
  (apply (car msg) state (cdr msg)))

2.1 基于函数的消息,具有状态调度和通过闭包传递的参数(来自 RowPJ 的评论)

(defclass state () ())

(defgeneric bazinga (object arg1 arg2))

(defmethod bazinga ((object state) arg1 arg2)
  (format t "arg1 = ~a, arg2 = ~a~%" arg1 arg2))

(let ((state (make-instance 'state))
      (msg (lambda (obj) (bazinga obj 10 20))))
  (funcall msg state))
  1. 基于函数的消息,"hardcoded dispatch"。
(defclass state () ()) ; could be a structure instead

(defun state-bazinga (object arg1 arg2)
  (format t "arg1 = ~a, arg2 = ~a~%" arg1 arg2))

(let ((state (make-instance 'state))
      (msg (list #'state-bazinga 10 20))) ; message example
  (apply (car msg) state (cdr msg)))

3.1 - 与 2.1 类似,此处略过。

我不太可能有任何类型的对象层次结构,所以我觉得这些样式之间没有真正的区别。那么,这真的只是个人喜好问题,还是有 objective 利弊?随着程序的发展,这些样式中的任何一种都可能更易于使用,还是会受到更多限制?我知道这不是一个明确的问题,但希望它仍然相当清楚我在问什么。

call functions in various threads

一个基本模型是一个等待循环,它监视自己的队列/邮箱并执行放入该队列/邮箱的功能。

将您想要的任何函数放入该队列。

这可以扩展为将函数及其参数入队。

LispWorks GUI 库使用该模型:apply-in-pane-process

心智模型很简单,就是APPLY在一个特定的进程中执行:apply-in-process <process> <function> <args>。在 Lisp 中,我首先想到的是函数式。 APPLY 是一个基本的函数调用操作符。现在使用类似的版本,它只是在特定进程中应用。然后可以应用 lambda、闭包、命名函数、CLOS 函数,...

有了它,就可以实现自己想要的各种调用约定。