3

私はClojureの初心者のようなものです。出力ストリームに書き込もうとしている複数のスレッドがあり、ソケットとそれらのストリームがスレッドセーフではない場合、それらに同時に書き込むとビットが混同される可能性があります。clojure の主な利点の 1 つは、競合状態の同時実行処理が組み込まれていることです。これを自分のシナリオでどのように利用できますか?

アトムや参照などを調べてみました。私は当初、出力ストリームをアトムとして宣言することでうまくいくと思っていましたが、(スワップを使用して) アトムの状態を同時に変更することを回避しているように見えるため、よくわかりませんが、複数のスレッドからアトムを逆参照できると思います。つまり、複数のスレッドが出力ストリームを保持しているアトムを逆参照し、同時に書き込みます。

どんなアドバイスも最も役に立ちます。

前もって感謝します

(defn send-my-data [output data-bytes]
  (try 
    (.write output)
    (.flush output)
    (catch Exception excp
       (println (format "issue %s" (.printStackTrace excp))))

これで、出力ストリームにデータを書き込みたいときはいつでも、すべてのスレッドがこの関数を呼び出します

4

3 に答える 3

1

他のスレッドがオブジェクトを使用していないことを確認する必要がある場合に使用できlockingます (そして、コード内のその時点で待機し、そのオブジェクトがロック解除されるまでその特定のスレッドで何もしないで、ロックできるようにする必要があります)。

user> (dotimes [i 10] (future (println \h \e \l \l \o)))
hhh h e
nil
 eh  le  l lo 
h e lh he  e ll h  el  ll  lo 
e  e l l oh
l l oo
l  ol

l lo o

 e

o
 l l o

user> (dotimes [i 10] (future (locking *out* (println \h \e \l \l \o))))
h
nil
 e l l o
h e l l o
h e l l o
h e l l o
h e l l o
h e l l o
h e l l o
h e l l o
h e l l o
h e l l o

user> 
于 2013-10-10T20:44:23.053 に答える
0

より慣用的であり、エージェントの他の利点があると思ったので、最終的にエージェントメソッドを実装しました。

(let [wtr (agent (.getOutputStream mysocket) "agent.log")]
    (defn log [msg]
      (letfn [(write [out msg]
             (.write out msg)
             (.flush out)
                out)]
      (send-off wtr write msg)))
  (defn close []
        (send wtr #(.close %))))

ここから適応

エージェントが戻り値を受け取るときに、出力ストリームを返すことを忘れないでください。よくある間違い。

ありがとうアーサー・ウルフェルト

于 2013-12-01T18:44:48.877 に答える