使文件写入线程安全化

8
我有一个在Ruby文件中写入文件的函数,像这样:
File.open("myfile", 'a') { |f| f.puts("#{sometext}") }

该函数在不同的线程中被调用,因此像上面那样的文件写入不是线程安全的。有没有人知道如何以最简单的方式使这个文件写入线程安全?
更多信息:如果有影响的话,我正在使用rspec框架。
3个回答

12

你可以通过File#flock来提供锁。

File.open("myfile", 'a') { |f| 
  f.flock(File::LOCK_EX)
  f.puts("#{sometext}") 
}

3

参考文章:http://blog.douglasfshearer.com/post/17547062422/threadsafe-file-consistency-in-ruby

这篇文章主要介绍了如何在Ruby中实现线程安全的文件一致性。通过使用互斥锁和文件锁,可以确保多个线程同时写入文件时不会出现数据损坏或丢失的情况。同时,还介绍了如何在Windows和Linux系统上实现文件锁的方法,并提供了相关的代码示例。
def lock(path)
  # We need to check the file exists before we lock it.
  if File.exist?(path)
    File.open(path).flock(File::LOCK_EX)
  end

  # Carry out the operations.
  yield

  # Unlock the file.
  File.open(path).flock(File::LOCK_UN)
end

lock("myfile") do
  File.open("myfile", 'a') { |f| f.puts("#{sometext}") }
end

1
我写的一个简单的日志记录器:

require 'fileutils'

module DebugTools
  class Logger
    def self.log(message)
      FileUtils.touch(path) unless File.exist?(path)

      lock(path) do |file|
        file.puts(message)
      end
    end

    def self.lock(path, &block)
      File.open(path, 'a') do | file |
        file.flock(File::LOCK_EX)
        block.call(file)
        file.flock(File::LOCK_UN)
      end
    end

    def self.path
      "#{Rails.root}/log/debugtools.log"
    end
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接