Should Process.fork affect file io in Ruby? -
i have been using process.fork
within observable object, have found interfering output observer object's file output.
when comment out process
lines, file output contains 16 lines each in order numbered 0-15. however, when uncommented file contains 136 lines of unordered numbers between 0-15. whether process
commented out or not, correct numbers printed screen.
is behaviour partially expected, or bug? has got ideas how around this?
the code below reproduces problem , created stripping original code until there enough demonstrate issue. original reason using process.fork
create several processes speed processing.
require 'observer' class recorder def initialize(notifier, filename) notifier.add_observer(self) @save_file = file.open(filename, 'w') @i = 0 end def update puts @i @save_file.puts @i @i += 1 end def stop @save_file.close end end class notifier include observable def run 16.times # when following 2 process lines uncommented, # file output recorder above erratic process.fork {exit} process.wait changed notify_observers end end end notifier = notifier.new recorder = recorder.new(notifier, 'test.data') notifier.run recorder.stop
when fork, child process contain clone of parent's open file, whatever data pending in buffer. when child exits flush data , close open file. doesn't effect parent's or siblings' open files, since map same kernel fd data goes same output file.
the first time through fork, there's no pending output, child wont write when exists. second time, there's "0\n" pending write when exits, next time, there's "0\n1\n" buffered, etc. forked processes may not exit in order they're created (they're asynchronous), hence jumbled results.
forks preserve open files , sockets, 1 needs careful mange them carefully.
you can fix behavior telling ruby flush output on each write instead of buffering.
class recorder def initialize(notifier, filename) notifier.add_observer(self) @save_file = file.open(filename, 'w') @save_file.sync = true # don't buffer file @i = 0 end end
Comments
Post a Comment