首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通用Lisp中的消息队列

通用Lisp中的消息队列
EN

Code Review用户
提问于 2012-07-26 02:47:28
回答 1查看 641关注 0票数 3

关于改变的一般建议。这是消息队列的实现,我将在参与者模型库上使用它。

代码语言:javascript
运行
复制
(defclass message-queue ()
  ((messages :accessor messages :initarg :messages :initform nil)
   (last-cons :accessor last-cons :initarg :last-cons :initform nil
    :documentation "Cached end of the list")
   (len :accessor len :initarg :len :initform 0
    :documentation "Cached message queue length. Modified by enqueue and dequeue")
   (lock :initform (bt:make-lock) :accessor lock
    :documentation "Lock for this message queue")
   (max-len :accessor max-len :initarg :max-len :initform nil
    :documentation "If present, queue maintains at most this many elements")
   (flag :initform (bt:make-condition-variable) :accessor flag
    :documentation "Condition variable used to notify that a message was enqueued")))

(defun make-queue (&optional max-len) 
  (make-instance 'message-queue :max-len max-len))

(defmethod full-p ((queue sized-queue))
  (with-slots (len max-len)
      (and max-len (>= len max-len))))

(defmethod empty-p ((queue message-queue)) 
  (= (len queue) 0))

(defmethod enqueue (object (queue message-queue))
  "Adds an element to the back of the given queue in a thread-safe way."
  (with-slots (lock messages max-len len flag last-cons) queue
    (with-lock-held (lock)
      (let ((o (list object)))
    (cond ((empty-p queue)
           (setf messages o 
             last-cons messages
             len 1))
          ((full-p queue)
           (pop messages)
           (setf (cdr last-cons) o 
             last-cons o))
          (t (setf (cdr last-cons) o
               last-cons o)
         (incf len)))))
    (condition-notify flag)
    messages))

(defmethod dequeue ((queue message-queue) &optional (timeout 0))
  "Pops a message from the given queue in a thread-safe way.
If the target queue is empty, blocks until a message arrives.
If timeout is not zero, errors after timeout."
  (with-slots (messages lock flag len) queue 
    (with-timeout (timeout)
      (with-lock-held (lock)
    (unless messages (condition-wait flag lock))
    (decf len)
    (pop messages)))))

(defmethod dequeue-no-hang ((queue message-queue))
  "Pops a message from the given queue in a thread-safe way.
If the target queue is empty, returns NIL.
The second value specifies whether an item was found in queue (this is meant
to disambiguate the situation where a queue contains the message NIL)"
  (with-slots (messages lock flag len) queue
    (with-lock-held (lock)
      (if messages
      (progn
        (decf len)
        (values (pop messages) t))
      (values nil nil)))))
EN

回答 1

Code Review用户

发布于 2012-10-26 15:20:22

我注意到您在消息队列类的所有插槽上定义了完整的读/写访问器,但是您绕过了所有这些,只使用-槽。您计划将这些访问器作为API的一部分导出吗?似乎你不想鼓励人们去玩那些插槽值,所以很可能不想。你也可以放弃:从除了马斯伦以外的一切。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/14036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档