问题描述
我正在尝试使用多个线程写出文本文件,但是下面的代码给了我一个例外-IOError: closed stream
threads = []
File.open("test.txt","a") do |fp|
500.times do |time|
threads << Thread.new do
fp.puts("#{time}: 1")
sleep(rand(100) / 100.0)
fp.puts("#{time}: 2")
end
end
end
threads.each{ |thread| thread.join }
解决方法
将连接移到file.open块内:
threads = []
File.open("test.txt","a") do |fp|
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{ |thread| thread.join }
end
为什么? Thread.new
启动线程,但是它并行运行,并且不能保证您版本中的线程的生存期短于文件的生存期。退出附加的块后,File.open
将关闭文件。通过等待关闭文件直到所有线程完成,一切都会按预期工作。
但是,请注意,此 IS NOT 线程在JRuby(或没有GIL的任何其他实现)上安全,并且可能混合了输出:
6: 1
5: 17: 1
8: 1
3: 10: 110: 1
4: 11: 1
2: 19: 1
11: 1
12: 1
13: 1
14: 1
注意:这个问题似乎来自Ruby MRI 1.8.7 - File writing thread safety