以原子方式读写文件

Read and write file atomically

我想在 Ruby 多个独立的 Ruby 进程(不是线程)之间以原子方式读写文件。

我是否需要实现自己的单独 'lock' 文件,以便在读取和写入之前进行检查?或者文件系统中是否已经存在更好的机制来将文件标记为 'busy' 我可以在任何 read/write 之前检查?


动机是愚蠢的,但包括在这里因为你要问它。

我有一个使用 Sinatra and served by Thin 的 Web 应用程序,它(出于自身原因)使用 JSON 文件作为 'database'。对服务器的每个请求都会读取文件的最新版本,进行任何必要的更改,然后将更改写入文件。

如果我只有一个服务器实例就没问题了运行。但是,我正在考虑在 Apache 反向代理后面放置多个 Thin 运行 副本。这些是离散的 Ruby 进程,因此 运行 真正并行。

经过进一步思考,我意识到我真的很想使读取-处理-写入行为成为原子操作。此时我意识到这基本上迫使我一次只能处理一个请求,因此没有理由拥有多个实例 运行。但对原子读取和在写入期间防止读取的好奇心仍然存在。因此问题。

您想在独占模式下使用 File#flock。这是一个小演示。 运行 这在两个不同的终端 windows.

filename = 'test.txt'

File.open(filename, File::RDWR) do |file|
  file.flock(File::LOCK_EX)

  puts "content: #{file.read}"
  puts 'doing some heavy-lifting now'
  sleep(10)
end

查看 "pstore.rb"(Ruby stdlib)中的 transactionopen_and_lock_file 方法。

YAML::Store 对我来说很好用。因此,当我需要以原子方式 read/write 时,我(ab)使用它来将数据存储为 Hash.