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

1

別の回答で提案されているようにファイルをフラッシュしても、このコードの動作は非決定論的であることに注意してください。たとえば、生成された 10 個すべてfuturesが最初にスケジュールされるまでに時間がかかる可能性があります。そのため、それらが開始される前に、-main関数は既に(close ofile)ロガーのアクションをキューに入れています。その場合、書き込みの試みはすべて失敗します。実際、shutdown-agents先物が開始する前に呼び出された可能性もあります。その場合、それらのsendアクションはまったく効果がありません!

于 2013-04-17T22:30:22.280 に答える