2012-03-10 15 views
1

私は観察可能なオブジェクト内でProcess.forkを使用していましたが、観察者オブジェクトのファイル出力からの出力を妨げていることがわかりました。Process.forkはRubyのファイルioに影響を与えるはずですか?

私がProcess行をコメントアウトすると、出力されるファイルには、0〜15の番号順にそれぞれ16行が含まれます。ただし、コメントを外すと、ファイルに0〜15の間に136行の順序付けられていない数値が含まれます。 Processがコメントアウトされているかどうかにかかわらず、正しい番号が画面に印刷されます。

この動作は部分的に期待されていますか、これはバグですか?誰かがこれを回避する方法を知っていますか?

以下のコードは問題を再現し、問題を示すのに十分なものがなくなるまで元のコードを元に戻して作成しました。 Process.forkを使用する元の理由は、処理を高速化するためにいくつかのプロセスを作成することでした。

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 do 
     # When the following two Process lines are uncommented, 
     # the file output from the Recorder above is 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 

答えて

4

あなたはフォーク、子プロセスは、データがそのバッファ内に保留されているもので、親のオープンファイルのクローンを、含まれています。子プロセスが終了すると、このデータがフラッシュされ、開いているファイルが閉じられます。これは、親ファイルや兄弟ファイルのオープンファイルには影響しませんが、すべて同じカーネルfdにマップされるため、すべてのデータが同じ出力ファイルに送られます。

フォークを初めて使用すると、保留中の出力がないので、子が存在する場合は何も書き込まれません。 2回目は、終了時に書き込みを行う "0 \ n"が保留されます。次回は "0 \ n1 \ n"がバッファリングされます。フォークされたプロセスは作成された順に終了しません彼らは非同期です)、あなたの混乱した結果。

フォークは開いているファイルとソケットを保持しているので、注意深く管理する必要があります。

おそらく、この動作は、バッファリングの代わりに各書き込みで出力をフラッシュするようにrubyに指示することで解決できます。

class Recorder 
    def initialize(notifier, filename) 
    notifier.add_observer(self) 
    @save_file = File.open(filename, 'w') 
    @save_file.sync = true # don't buffer this file 
    @i = 0 
    end 
end 
+0

ありがとうございました。私はあなたの答えを編集しましたが、同期ラインは違いはありませんでしたが、原則は正しいものであり、代わりにフラッシュを使用して動作します。 –

+0

IO#sync =あなたのために働いていないのが不思議です。あなたのコードで@ save_file.sync = trueを試したところ、ruby 1.9.2p180(2011-02-18 revision 30909)[x86_64-linux]とruby 1.8.7(2010-01-10 patchlevel 249)[x86_64 -linux] – dbenhur

関連する問題