gpt4 book ai didi

Ruby MRI 1.8.7 - 文件写入线程安全

转载 作者:数据小太阳 更新时间:2023-10-29 07:34:20 24 4
gpt4 key购买 nike

在我看来,用 Ruby MRI 1.8.7 编写文件是完全线程安全的。

示例 1 - 完美结果:

File.open("test.txt", "a") { |f|
threads = []
1_000_000.times do |n|
threads << Thread.new do
f << "#{n}content\n"
end
end
threads.each { |t| t.join }
}

示例 2 - 完美的结果(但速度较慢):

threads = []
100_000.times do |n|
threads << Thread.new do
File.open("test2.txt", "a") { |f|
f << "#{n}content\n"
}
end
end
threads.each { |t| t.join }

所以,我无法重建我面临并发问题的场景,你可以吗?

如果有人能向我解释为什么我仍然应该在这里使用 Mutex,我将不胜感激。

编辑:这是另一个更复杂的例子,它工作得很好并且没有显示并发问题:

def complicated(n)
n.to_s(36).to_a.pack("m").strip * 100
end

items = (1..100_000).to_a

threads = []
10_000.times do |thread|
threads << Thread.new do
while item = items.pop

sleep(rand(100) / 1000.0)
File.open("test3.txt", "a") { |f|
f << "#{item} --- #{complicated(item)}\n"
}

end
end
end
threads.each { |t| t.join }

最佳答案

我也无法产生错误。

您可能在这里遇到了文件锁定。如果您希望多个线程写入同一个文件,它们应该都使用相同的文件对象,如下所示:

File.open("test.txt", "a") do |fp|
threads = []

500.times do |time|
threads << Thread.new do
fp.puts("#{time}: 1")
sleep(rand(100) / 100.0)
fp.puts("#{time}: 2")
end
end

threads.each(&:join)
end

在这个例子中,GIL 可能会避免任何真正的线程错误,但我不太确定,在 JRuby 下会发生什么,它使用真正的线程并且两个写入可能同时发生。其他具有真正线程的 Ruby 引擎也是如此。

关于您应该在何处用锁保护您的代码的问题归结为,如果您想依赖您正在使用的 Ruby 引擎应该拯救您,或者您想要编写一个“应该”适用于所有系统的解决方案Ruby 引擎,不管它们是否有内置功能来避免并发问题。

另一个问题是,您的操作系统和/或文件系统是否正在使用文件锁将您从线程错误中拯救出来,以及您的代码是否应该独立于操作系统和/或文件系统,这意味着您不会依赖在文件系统锁上,以确保您的文件打开和写入由操作系统和/或文件系统正确同步。

我会大胆地说,这似乎是个好习惯,你也可以在你这边实现锁,以确保你的代码保持工作,无论是哪个 Ruby 引擎、操作系统或文件系统即使大多数现代 Ruby 引擎、操作系统和文件系统都内置了这些功能,其他人也会使用您的代码。

关于Ruby MRI 1.8.7 - 文件写入线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15108424/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com