Ruby IO.popen with “-” , what happens under the hood?
我试图理解io.popen的命令是
关于这个主题没有太多的材料,我正在慢慢地理解它们,主要是因为我只是为了好玩而编写代码。
据我所知,当调用
这一次,它帮助我理解这个问题,这个块是io.popen命令的一部分。
我有这个代码:
1 2 3 4 5 6 7 8 9 | 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 块有关,但它们是。对我来说,pipe 是一个文件句柄(就像在旧的turbo pascal中一样),它首先在某个地方定义,然后在其他地方操作。
没有人决定先运行哪个进程。子进程可以先运行,或者父进程可以先运行,操作系统可以以任何方式调度它们。
这意味着父进程可以在子进程完成之前完成。当父进程完成时,它的管道将关闭,当子进程写入它时,它将得到一个异常。这就是代码中发生的事情。
为什么没有注释行就不会发生呢?当您在父进程中调用
尝试以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
它等待直到孩子关闭管道(然后