Estoy tratando de entender cómo funciona IO.pipe en Ruby. En el siguiente ejemplo, envío datos a la tubería io y cierro la transmisión después de terminar de enviar los datos. En un proceso secundario, leo los datos usando el método readpartial. De acuerdo con los documentos, readpartial debería generar EOFError cuando la transmisión está cerrada, pero termino con un proceso bloqueado, ¿lo entiendo bien?

# ruby 2.6.3
r, w = IO.pipe

pid = fork do
  loop do
    puts r.readpartial(1024)
    sleep 0.1
  rescue EOFError
    puts "End of File"
    break
  end
end

1000.times do |t|
  w.write "xyz #{t}"
end

w.close

Process.wait(pid)
1
Needless Wolf 26 ago. 2020 a las 15:41

1 respuesta

La mejor respuesta

Debe cerrar el extremo de escritura de la tubería en el niño y en el padre.

Después de la bifurcación, efectivamente tiene dos extremos de escritura y dos extremos de lectura en la tubería. Cuando cierra el extremo de escritura en el padre, el extremo de escritura en el hijo todavía está abierto, por lo que la llamada a readpartial se bloqueará.

Solo necesita llamar a w.close inmediatamente después de bifurcar al niño:

pid = fork do
  w.close
  loop do
    #...

Normalmente, también cerraría inmediatamente el final de lectura en el padre después de la bifurcación (aunque en este caso realmente no importa):

pid = fork do
  #...
end

r.close
1
matt 27 ago. 2020 a las 03:28