Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Process.fork应该影响Ruby中的文件io吗?_Ruby_Fork - Fatal编程技术网

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

Process.fork应该影响Ruby中的文件io吗?,ruby,fork,Ruby,Fork,我在一个可观察对象中使用了Process.fork,但发现它干扰了观察对象文件输出的输出 当我注释掉过程行时,输出的文件包含16行,每行的顺序为0-15。但是,当取消注释时,文件包含136行0-15之间的无序数字。无论过程是否被注释掉,正确的数字都会打印到屏幕上 这是部分预期的行为,还是一个bug?有人知道怎么避开这件事吗 下面的代码再现了这个问题,它是通过剥离原始代码创建的,直到有足够的代码来演示这个问题。使用Process.fork的最初原因是创建几个进程以加快处理速度 需要“观察者” 课堂

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

当我注释掉
过程
行时,输出的文件包含16行,每行的顺序为0-15。但是,当取消注释时,文件包含136行0-15之间的无序数字。无论
过程
是否被注释掉,正确的数字都会打印到屏幕上

这是部分预期的行为,还是一个bug?有人知道怎么避开这件事吗

下面的代码再现了这个问题,它是通过剥离原始代码创建的,直到有足够的代码来演示这个问题。使用
Process.fork
的最初原因是创建几个进程以加快处理速度

需要“观察者”
课堂记录员
def初始化(通知程序,文件名)
通知者。添加观察者(自身)
@save_file=file.open(文件名“w”)
@i=0
终止
def更新
放置@i
@保存_file.puts@i
@i+=1
终止
def停止
@保存文件。关闭
终止
终止
类通知程序
包括可观察的
def运行
16.5倍
#当以下两个流程行未注释时,
#上述记录器的文件输出不稳定
Process.fork{exit}
等等
改变
通知观察员
终止
终止
终止
notifier=notifier.new
recorder=recorder.new(通知程序'test.data')
通知程序.run
停

分叉时,子进程将包含父进程打开的文件的克隆,其缓冲区中有任何挂起的数据。当子级退出时,它将刷新此数据并关闭其打开的文件。这不会影响父级或同级打开的文件,但因为它们都映射到同一内核fd,所以所有数据都会转到同一输出文件

第一次通过fork时,没有挂起的输出,这样子级就不会在它存在时写入任何内容。第二次,有一个“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

分叉时,子进程将包含父进程打开的文件的克隆,其缓冲区中有任何挂起的数据。当子级退出时,它将刷新此数据并关闭其打开的文件。这不会影响父级或同级打开的文件,但因为它们都映射到同一内核fd,所以所有数据都会转到同一输出文件

第一次通过fork时,没有挂起的输出,这样子级就不会在它存在时写入任何内容。第二次,有一个“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

谢谢,上面的工作。我编辑了你的答案,因为同步线没有什么区别,但原理是正确的,可以用flush代替。奇怪的是,IO#sync=不适合你。我用你的代码尝试了@save_file.sync=true,它与ruby 1.9.2p180(2011-02-18修订版30909)[x86_64-linux]和ruby 1.8.7(2010-01-10 patchlevel 249)[x86_64-linux]一起工作,谢谢,上面的工作正常。我编辑了你的答案,因为同步线没有什么区别,但原理是正确的,可以用flush代替。奇怪的是,IO#sync=不适合你。我在你的代码中尝试了@save_file.sync=true,它与ruby 1.9.2p180(2011-02-18修订版30909)[x86_64-linux]和ruby 1.8.7(2010-01-10 patchlevel 249)[x86_64-linux]