3

我正在玩线程安全文件写入,但我不知道为什么这段代码没有记录到文件中(基于代理部分:http ://blakesmith.me/2012/05/25/understanding -clojure-concurrency-part-2.html )

代码运行了所有正确的功能,但文件仍然是空的。我认为这是因为文件关闭没有以某种方式发生,但即使取消期货以强制关闭最后作为测试似乎也无济于事。

(defn write-out [out msg]
  (.write out msg)
  out)

(defn log [logger msg]
  (send logger write-out msg))

(defn close [logger]
  (send logger #(.close %)))

(defn go []
  (let [ofile (agent (clojure.java.io/writer "/tmp/log.test.txt" :append true))]
    (dotimes [x 10]
      (future (log ofile (str "Log A " x "\n"))))
    (close ofile)
    (shutdown-agents)))

小红利问题:链接的帖子从未真正解释为什么我需要在写出结束时返回文件写入器指针。我知道你需要它,但我不知道为什么。

4

2 回答 2

3

也许你需要打电话(.flush out)

您的函数需要返回out,以便代理在defn它收到的下一次调用中具有该值。写入文件本身就是一个副作用。

an 的典型示例用例agent是由多个线程“递增”(好吧,被新的递增值替换)的计数器。但是,在这种情况下,您不会增加计数器,而是写入out(OutputStream实例)。所以out必须返回,以便将其传递给下一个代理任务。

我发现有用的博文:http: //lethain.com/a-couple-of-clojure-agent-examples/

于 2013-04-17T16:40:30.177 回答
1

请注意,即使您按照另一个答案中的建议刷新文件,此代码的行为也是不确定的。例如,可能所有 10 个生成futures的对象在第一次被安排之前都需要一段时间,因此在它们开始之前,该-main函数已经(close ofile)在记录器上排队了一个操作:在这种情况下,所有写入尝试都将失败。事实上,甚至可能shutdown-agents在任何期货开始之前就已经被调用:那么他们的send任何行动都不会产生任何影响!

于 2013-04-17T22:30:22.280 回答