问题
I am trying to write out to a text file using multiple threads, however the code below gives me an exception - 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 }
回答1:
Move the join inside the file.open block:
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
Why? Thread.new
launches the thread, but it runs in parallel, and the life of the thread in your version isn't guaranteed to be shorter than the life of the file. File.open
closes the file after you exit the attached block. By waiting to close the file until after all the threads are done, everything will work as expected.
However, please note that this IS NOT thread safe on JRuby (or any other implementation without a GIL) and may have output intermixed:
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
Note: this question appears to be from Ruby MRI 1.8.7 - File writing thread safety
来源:https://stackoverflow.com/questions/64352404/writing-to-a-file-from-multiple-threads