gpt4 book ai didi

ruby - Process.fork 应该影响 Ruby 中的文件 io 吗?

转载 作者:太空宇宙 更新时间:2023-11-03 17:58:16 25 4
gpt4 key购买 nike

我一直在可观察对象中使用 Process.fork,但发现它干扰了观察者对象文件输出的输出。

当我注释掉 Process 行时,输出的文件包含 16 行,每行按 0-15 的顺序编号。但是,当取消注释时,该文件包含 136 行 0-15 之间的无序数字。无论 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

最佳答案

当您 fork 时,子进程将包含父进程打开文件的克隆,以及其缓冲区中未决的任何数据。当 child 退出时,它将刷新此数据并关闭其打开的文件。这不会影响 parent 或 sibling 打开的文件,但由于它们都映射到同一个内核 fd,因此所有数据都将转到同一个输出文件。

第一次通过 fork 时,没有待处理的输出,所以当它存在时, child 不会写任何东西。第二次,有一个“0\n”挂起,它将在退出时写入,下一次,有“0\n1\n”被缓冲,等等。 fork 进程可能不会按照它们创建的顺序退出(它们是异步的),因此你的结果很困惑。

Fork 保留打开的文件和套接字,因此需要小心谨慎地管理它们。

您可以通过告诉 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

关于ruby - Process.fork 应该影响 Ruby 中的文件 io 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9644602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com