Clojure对共享资源的异步访问

时间:2014-05-15 04:43:59

标签: multithreading sockets asynchronous clojure

我有一个TCP套接字连接,我需要在其中处理n个请求和conj每个请求,并且它是对向量的相应响应,用于记录目的。我需要通过两个异步线程进行传输和接收,其中transmit函数负责发送请求,receive函数负责接收来自服务器的响应。

我的理解是,对于异步传输,我需要在Clojure中使用agent来完成此任务。但是,我还需要确保对向量的串行访问,因为两个线程都试图在任何给定时间修改它。

我尝试了一些工作,但是我的代理人在提出一些请求并处理了一些回复后最终处于失败状态。

以下是显示我尝试做的代码。如果有人能给我一些指导,我们将不胜感激。

;; the shared resource

(def async-log (agent []))

;; I thought this needed to be synchronized for serial access, so I used 
;; dosync, but I am not sure if this is right. In any case, it doesn't 
;; seem to make a difference

(defn add-entry
  [coll entry]
  (dosync (conj coll entry)))

;; transmit function

(defn transmit
  [log writer socket request]
  (let [request   (request->String request socket)
        bytes-out (request->bytes request)
        length    (count bytes-out)]
    (.writeShort writer length)
    (.write writer bytes-out 0 length)
    (add-entry log request)))

;; Receive function

(defn receive
  [log reader socket]
  (let [length   (read-length reader)
        bytes-in (byte-array request/max-message-size)]
    (.read reader bytes-in 0 length)
    (add-entry log (to-string bytes-in))))

;; process each request, n times

(defn process-requests
  [request socket iters]
  (with-open [reader (DataInputStream. (.getInputStream socket))
              writer (DataOutputStream. (.getOutputStream socket))]
    (dotimes [x iters]
      (send-off async-log transmit writer socket request)
      (send-off async-log receive reader socket)
      (Thread/sleep 50))))

1 个答案:

答案 0 :(得分:1)

你是正确的,那里不需要你的dosync。

如果问题是您的座席正在进入错误状态,那么您应该使用以下功能:

agent-error调查代理商的错误。

restart-agent重置代理的错误状态,以便它可以再次运行。

set-error-handler!定义代理遇到错误时的行为。