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

Popular posts from this blog

delphi - How to convert bitmaps to video? -

jasper reports - Fixed header in Excel using JasperReports -

python - ('The SQL contains 0 parameter markers, but 50 parameters were supplied', 'HY000') or TypeError: 'tuple' object is not callable -