gpt4 book ai didi

带有 "-"的 Ruby IO.popen,背后发生了什么?

转载 作者:数据小太阳 更新时间:2023-10-29 08:54:13 24 4
gpt4 key购买 nike

我试图理解 IO.popen 当它的命令是 "-" 时它会启动一个新的 Ruby 解释器。

关于这个主题的 Material 不多,我正在慢慢地学习它们,主要是因为我只是为了好玩而编写代码。

据我所知,IO.popen("-", "w+") {|f| ...} 被调用 - 这是一个 block - 该 block 将由 父进程和子进程运行。不同的是父进程会因此得到一个IO对象,而子进程得到的只是一个Nil。这很简单,我需要检查 block 中的 |f| ,当它是 Nil 时,在子进程中执行,当它不是 nil 时,在父进程中执行。所以我必须为由 if 分隔的父子代码编写代码。

这次它帮助我理解了问题,该 block 是 IO.popen 命令的一部分

我有这个代码:

pipe = IO.popen("-","w+")
# puts "This line will break functionality if uncommented"
if pipe != nil then
pipe.puts "PID: #{Process.pid}"
$stderr.puts "Parent from child: #{pipe.gets.chomp}"
else
$stderr.puts "Child PID: #{Process.pid} and Parent #{gets.chomp}"
puts "M'kay"
end

问题:

  • 什么决定哪个进程先运行?如果他们要附加一个文件,它是否容易受到竞争条件的影响?
  • 为什么第二行破坏了代码? pipe = IO.popen... 命令不应该与 if..else..end block 相关,但它们是。对我来说,pipe 是一个文件句柄(就像在旧的 Turbo Pascal 中一样),它首先在某处定义,然后在别处操作。

最佳答案

没有人决定哪个进程先运行。子进程可能首先运行——或者父进程可能首先运行——操作系统可能以任何一种方式安排它们。

这意味着父进程可能会在子进程完成之前完成。当父进程完成时,它的管道关闭,当子进程写入它时,它会得到一个异常。这就是您的代码中发生的情况。

为什么没有注释行就不会发生?当您在父进程中调用 gets 时,它会一直等到子进程向管道写入一行。这意味着在 child 向管道写入一行之前, parent 不会完成,而这忽略了这个问题。但是,当您打印两行时,父进程在子进程执行第二个 puts "M'kay" 之前终止的几率会增加。

试试下面的代码:

pipe = IO.popen("-","w+")
puts "This line will not break functionality"
puts "This line will not break functionality"
puts "This line will not break functionality"
if pipe != nil then
pipe.puts "PID: #{Process.pid}"
while line = pipe.gets
$stderr.puts "Parent from child: #{line.chomp}"
end
else
$stderr.puts "Child PID: #{Process.pid} and Parent #{gets.chomp}"
puts "M'kay"
end

它一直等到 child 关闭管道(然后 pipe.gets 将返回 nil),这发生然后它终止,并确保它不会试着写在那里。

关于带有 "-"的 Ruby IO.popen,背后发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5611752/

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