私はキューにファイルへの書き込みを含む先物処理ジョブのグループを持っています。 1人の未来だけが特定のファイルに一度にアクセスするようにするための慣用的な方法は何ですか?clojureで慣用的なファイルロック?
答えて
これを保証するには、ロックの代わりにエージェントを使用しますか?
私は、ロックやロックを使用するよりも、メモリやディスクにあるかどうかに関係なく、安全なガード共有可変状態にすることを考えています。
一度に1つのエージェントを作成し、そのエージェントにアクセス試行を送信すると、特定のファイルにアクセスするときにスレッド上でのみ確実にアクセスできるようになります。
(use 'clojure.contrib.duck-streams)
(defn file-agent [file-name]
(add-watch (agent nil) :file-writer
(fn [key agent old new]
(append-spit file-name new))))
(defn async-append [file-agent content]
(send file-agent (constantly content)))
、エージェントを通して、あなたのファイルを追加します:
(async-append "content written to file" (file-agent "temp-file-name"))
あなたはファイルの同期の使用が必要な場合、それはのawaitを達成することができた。このような例
。このように:
(defn sync-append [file-agent content]
(await (send file-agent (constantly content))))
私はClojureにこれ用の組み込み関数があるとは思っていませんが、標準のJava IO関数を使ってこれを行うことができます。これは次のようになります。
(import '(java.io File RandomAccessFile))
(def f (File. "/tmp/lock.file"))
(def channel (.getChannel (RandomAccessFile. f "rw")))
(def lock (.lock channel))
(.release lock)
(.close channel)
最初にこの方法を試しましたが、残念ながらこの方法はファイルを他のプロセスからのアクセスからロックするためにのみ有効です。同じVM内の複数のスレッドを操作する場合、ファイルが使用可能になるまでブロックしないで、同じVM内の別のスレッドがすでにファイルをロックしていると、lockとtryLockは両方とも例外をスローします。 – jhickner
私は次のように使用されているコアClojureの機能lockingを使用します。ここでは
(locking some-object
(do-whatever-you-like))
some-object
は、ファイル自体も、あるいはあなたが同期したい任意のオブジェクト可能性がどちらか(複数のファイルを1つのロックで保護したい場合には意味があります)。
標準ではJVMのオブジェクトロックが使用されているため、基本的にはJavaのコードブロックと同期しています。
- 1. Clojure:慣用的なClojureファッションでjava.util.HashMapを使用する
- 2. この慣用のClojureですか?
- 3. Clojure:ベクトルの慣用加重平均
- 4. Clojureのリストでは、慣習的で怠け者です。
- 5. Clojureにnil-punningの慣用的な代替手段はありますか?
- 6. clojureには慣用的な方法のハンドル状態がありますか?
- 7. Clojureでは、nsマクロではなくrequire ...を使用するのが慣用的に正しいですか?
- 8. ClojureでこのPythonを表現するための機能的/慣用的な方法
- 9. Clojureで複数のベクトルを合計する慣習的な方法
- 10. Clojureでインデックス付きのステートフルルックアップテーブルを保持する慣習的な方法
- 11. Clojureでマップをスライスする慣用方法は何ですか?
- 12. 慣用的方法
- 13. このJavaの例を慣用的なClojureに変換するにはどうすればよいですか?
- 14. 慣用的な追加操作
- 15. 慣用的なJavascript依存関係グラフ
- 16. 慣用的なKotlinの正規表現
- 17. Clojure:等しくないサイズのリストからの要素のより慣用的なペアリング?
- 18. clojure: "if"の複製を削除する慣用方法?
- 19. 条件付きの慣用的な目的地/目的地
- 20. 長いClojure文字列リテラルを避けるための慣用的な方法はありますか?
- 21. バッチスクリプト - リダイレクト - 可能なファイルロック?
- 22. clojureの再帰的な(doall)
- 23. CollectionViewGroupグループを持つ慣用的なXAML TreeViewは何ですか?
- 24. 慣用的なスカラで連鎖する方法
- 25. shouldComponentUpdateの慣用的な実装ですか?
- 26. 慣れない基本的なC++コード
- 27. ファイルロックのテスト
- 28. ファイルロックCプログラミング
- 29. このコードを慣用的/機能的な方法で書くには?
- 30. 科学的なプログラミングの慣行
ニート!これについて私の頭を浮かべるには少し時間がかかりました。私は開いているファイルごとにエントリが含まれているマップへの参照を使用して終了しました。あなたのソリューションははるかに良いかもしれないように見えます。 – jhickner
私はまだ何かが不明です - もし2つのスレッドが両方ともasync-appendを呼び出して同じファイル名を渡した場合、ファイルを開くのを止めないでください。 async-append内のfile-agentを呼び出すと、スレッドごとに一意のエージェントが作成されるようですね。 – jhickner
不明な指示がありましたら申し訳ございませんが、ファイルごとに1つのファイルエージェントを作成し、非同期または同期追加が必要な場合は、async-appendまたはsync-appendのいずれかを使用して追加します。正しいエージェントを見つけるためにエージェントを地図の中に置いておくことができます。 –