Почему мой код никогда не достигает конца при ожидании трубы?

Я пытаюсь использовать IO.pipe для отправки сообщений между процессами, но сталкиваюсь с каким-то голоданием, когда жду сообщений о завершении.

Код: https://carc.in/#/r/12ly


person Hugo Abonizio    schedule 27.06.2016    source источник


Ответы (1)


Я вижу один w_waiter.puts и 2 раза r_waiter.gets, поэтому он блокируется. Если я добавлю еще один w_waiter.puts после первого, он закончится. В этом проблема?

РЕДАКТИРОВАТЬ: я также пробовал это в Ruby

r_producer, w_producer = IO.pipe
r_waiter, w_waiter = IO.pipe

2.times do |i|
  fork do
    puts "in fork #{i}"
    loop do
      message = r_producer.gets.chomp
      sleep 0.1
      puts "#{message} from #{i}"
      break if message == "0"
    end
    puts "sending finish"
    w_waiter.puts "finish"
  end
end

10.times do |i|
  w_producer.puts i + 1
end

2.times do
  w_producer.puts 0
end

2.times { r_waiter.gets }
puts "end of the program"

Тот же результат.

Я не уверен, что использование одного и того же канала для двух разветвленных процессов работает. Вы должны создать один канал для каждого процесса.

В качестве альтернативы (я не знаю, что у вас за программа) вы можете использовать порождение и каналы, как описано в руководстве по параллелизму: http://crystal-lang.org/docs/guides/concurrency.html

person asterite    schedule 27.06.2016
comment
Но запущены 2 процесса, оба они должны вызывать w_waiter.puts, когда цикл заканчивается, один застревает, а окончание отправки сообщения отображается только 1 раз. - person Hugo Abonizio; 27.06.2016
comment
Я только что попробовал это в Ruby, и я получаю те же результаты: - person asterite; 28.06.2016
comment
Я отредактировал ответ с кодом Ruby и кратким объяснением/догадкой - person asterite; 28.06.2016
comment
Моя цель - использовать канал в качестве IPC вместо каналов для нескольких процессов, какой подход должен быть лучшим? Unix-сокеты? - person Hugo Abonizio; 28.06.2016
comment
Можно ли использовать один канал для каждого процесса? - person asterite; 28.06.2016
comment
Это странно, я уменьшил пример, и это работает carc.in/#/r/12os но это зависает carc.in/#/r/12oq - person Hugo Abonizio; 28.06.2016