Ruby IO.popen,带“1”-&引用,引擎盖下发生了什么?

Ruby IO.popen,带“1”-&引用,引擎盖下发生了什么?,ruby,io,subprocess,popen,ruby-1.9.2,Ruby,Io,Subprocess,Popen,Ruby 1.9.2,我试图理解IO.popen的命令是“-”,它启动了一个新的Ruby解释器 关于这个主题的材料不多,我慢慢地读完了,主要是因为我只是为了好玩而编写代码 据我所知,当调用IO.popen(“-”,“w+”{| f |…}时(即使用块),该块将由父进程和子进程运行。不同之处在于,父进程将得到一个IO对象,而子进程只得到一个Nil。这很简单,我需要检查块中的| f |,当它为Nil时,执行在子进程中,当它不是Nil时,执行在父进程中。因此,我必须为父级和子级编写代码,用if分隔 这一次,它帮助我理解了这

我试图理解IO.popen的命令是
“-”
,它启动了一个新的Ruby解释器

关于这个主题的材料不多,我慢慢地读完了,主要是因为我只是为了好玩而编写代码

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

这一次,它帮助我理解了这个问题,即块是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
    块相关,但它们是。对我来说,
    pipe
    是一个文件句柄(就像旧的turbopascal一样),它首先在某个地方定义,然后在其他地方操作

    • 没有人决定先运行哪个进程。子进程可以先运行,或者父进程可以先运行。操作系统可以以任何方式调度它们

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

      为什么没有注释行就不会发生?当您在父进程中调用
      get
      时,它将等待子进程将一行写入管道。这意味着父级在子级向管道写入一行之前不会完成,而这忽略了这个问题。但是,当您打印两行时,父进程在子进程执行第二行“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
      
      它等待直到子级关闭管道(然后
      pipe.get
      将返回
      nil
      ),然后终止,并确保不再尝试在那里写入