我从一个涉及写入文件的队列中有一组期货处理作业。确保只有一个未来一次访问特定文件的惯用方法是什么?
答案 0 :(得分: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"))
如果您需要同步使用该文件,可以通过等待来实现。像这样:
(defn sync-append [file-agent content]
(await (send file-agent (constantly content))))
答案 1 :(得分:4)
我会使用核心Clojure函数locking,其使用方法如下:
(locking some-object
(do-whatever-you-like))
此处some-object
可以是文件本身,也可以是您想要同步的任意对象(如果您想要一个锁来保护多个文件,这可能是有意义的。)
在幕后,它使用标准的JVM对象锁定,因此它基本上等同于Java中的同步代码块。
答案 2 :(得分: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)