私はキューにファイルへの書き込みを含む先物処理ジョブのグループを持っています。 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にnil-punningの慣用的な代替手段はありますか?
- 4. Clojureでは、nsマクロではなくrequire ...を使用するのが慣用的に正しいですか?
- 5. Clojureでインデックス付きのステートフルルックアップテーブルを保持する慣習的な方法
- 6. Clojureで複数のベクトルを合計する慣習的な方法
- 7. Clojureでマップをスライスする慣用方法は何ですか?
- 8. 慣用的なJavascript依存関係グラフ
- 9. このJavaの例を慣用的なClojureに変換するにはどうすればよいですか?
- 10. clojure: "if"の複製を削除する慣用方法?
- 11. 長いClojure文字列リテラルを避けるための慣用的な方法はありますか?
- 12. バッチスクリプト - リダイレクト - 可能なファイルロック?
- 13. CollectionViewGroupグループを持つ慣用的なXAML TreeViewは何ですか?
- 14. 慣れない基本的なC++コード
- 15. clojureの再帰的な(doall)
- 16. ファイルロックのテスト
- 17. ファイルロックCプログラミング
- 18. 科学的なプログラミングの慣行
- 19. 健康的なプログラミングの慣行
- 20. Mac vs. Windows vs. Linuxの慣用的なアプリケーションデータ
- 21. ReentrantLockをConcurrencyパッケージで慣用的に使用する
- 22. clojureプログラムの慣用句(defn -main ...)は何を意味しますか?
- 23. clojureから非標準的な反復的なJava APIを使用したInterop
- 24. 慣用Javascriptを
- 25. スカラーDSLと型付き演算子:慣用的な実装ですか?
- 26. Rubyで慣用的にファサードを作成する
- 27. 古典的なWebアプリケーション用のClojureとnoir
- 28. Akka HTTPで基本的なHTTP POST要求を作成するための慣用的な方法
- 29. 静的なフィールドを持つのは悪い習慣ですか?
- 30. GOPATHフォルダへのシンボリックリンクは一般的な慣行ですか?
ニート!これについて私の頭を浮かべるには少し時間がかかりました。私は開いているファイルごとにエントリが含まれているマップへの参照を使用して終了しました。あなたのソリューションははるかに良いかもしれないように見えます。 – jhickner
私はまだ何かが不明です - もし2つのスレッドが両方ともasync-appendを呼び出して同じファイル名を渡した場合、ファイルを開くのを止めないでください。 async-append内のfile-agentを呼び出すと、スレッドごとに一意のエージェントが作成されるようですね。 – jhickner
不明な指示がありましたら申し訳ございませんが、ファイルごとに1つのファイルエージェントを作成し、非同期または同期追加が必要な場合は、async-appendまたはsync-appendのいずれかを使用して追加します。正しいエージェントを見つけるためにエージェントを地図の中に置いておくことができます。 –