我有一組來自隊列的期貨處理工作,涉及寫入文件。確保只有一個未來訪問特定文件的慣用方法是什麼?clojure中的慣用文件鎖定?
7
A
回答
8
如何使用代理而不是鎖來確保這一點?
我認爲使用代理來保護共享可變狀態,無論它在內存中還是在磁盤上比clojure更習慣於使用鎖。
如果您一次創建一個代理程序並將訪問嘗試發送給代理程序,則可以確保只在線程上訪問給定文件。
例如像這樣:
(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))))
1
我不認爲在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)
+0
我首先檢查了這條道路,但不幸的是,這個方法僅用於鎖定其他進程訪問文件。當在同一個虛擬機中使用多個線程時,如果同一虛擬機中的另一個線程已將文件鎖定,lock和tryLock都會引發異常,而不是在文件可用之前阻塞。 – jhickner
4
我會使用核心Clojure的功能locking這是用來如下:
(locking some-object
(do-whatever-you-like))
這裏some-object
既可以是您要同步的文件本身,或者任意對象(如果你想要一個鎖來保護多個文件,這可能是有意義的)。
底層使用標準JVM對象鎖定,所以它基本上等同於Java中的同步代碼塊。
相關問題
- 1. 這是慣用的Clojure嗎?
- 2. clojure中的慣用惰性原子
- 3. Clojure:在一個慣用的Clojure時尚中使用java.util.HashMap
- 4. 在Clojure中更習慣性地逐行處理文件
- 5. clojure的慣用選擇排序
- 6. clojure不純功能的慣用名
- 7. Clojure中的習慣模式功能
- 8. Clojure中的習慣表達簡化
- 9. 在Clojure地圖中更新給定密鑰的習慣方式?
- 10. 讓膨脹還是慣用clojure?
- 11. 用PhpStorm鎖定/解鎖文件
- 12. 使用C#鎖定文件#
- 13. 在AccuRev中鎖定文件
- 14. 在Python中鎖定文件
- 15. 在.NET中鎖定文件
- 16. 刪除用戶在perforce中解鎖所有鎖定的文件
- 17. C++中的文件鎖定用於同時讀寫鎖
- 18. 進展報告的習慣性clojure?
- 19. 解鎖鎖定的java文件Android studio
- 20. 跟蹤clojure中以前的值的慣用方法是什麼?
- 21. FileInfo鎖定文件!
- 22. HttpPostedFileBase鎖定文件
- 23. Java文件鎖定
- 24. PowerShell鎖定文件
- 25. Linux文件鎖定
- 26. System.Reflection.Assembly.LoadFile鎖定文件
- 27. 鎖定XML文件
- 28. System.IO.File.Create鎖定文件
- 29. Clojure的文件
- 30. clojure:消除「if」中重複的慣用方法?
整潔!花了一點時間纔想起這件事。我最終使用了一個地圖,其中包含每個打開文件的條目。你的解決方案看起來好像更好。 – jhickner
我仍然不清楚什麼 - 如果兩個線程都調用async-append並傳入相同的文件名,那麼如何避免它們同時打開文件?看起來在async-append中調用file-agent會爲每個線程創建一個唯一的代理,對吧? – jhickner
對不清楚的說明,我打算爲每個文件創建一個文件代理,然後通過異步追加或同步附加追加它,這取決於您是否需要異步或同步追加。你可以讓他們自己的代理人在地圖上找到正確的代理人。 –