Подтвердить что ты не робот

Как я могу вернуть значение из потока в Ruby?

Если у меня есть следующий код:

threads = []
(1..5).each do |i|
  threads << Thread.new { `process x#{i}.bin` } 
end
threads.each do |t|
  t.join
  # i'd like to get the output of the process command now.
end

Что мне нужно сделать, чтобы получить вывод команды процесса? Как я могу создать пользовательский поток, чтобы выполнить это?

4b9b3361

Ответ 1

script

threads = []
(1..5).each do |i|
  threads << Thread.new { Thread.current[:output] = `echo Hi from thread ##{i}` }
end
threads.each do |t|
  t.join
  puts t[:output]
end

иллюстрирует, как выполнить то, что вам нужно. Он имеет преимущество сохранения вывода с потоком, который сгенерировал его, поэтому вы можете в любой момент присоединиться и получить выход каждого потока. При запуске script печатает

Hi from thread #1
Hi from thread #2
Hi from thread #3
Hi from thread #4
Hi from thread #5

Ответ 2

Мне было проще использовать коллекцию для сбора потоков в списке и использовать thread.value для объединения и возврата значения из потока - это обрезает его до:

#!/usr/bin/env ruby
threads = (1..5).collect do |i|
  Thread.new { `echo Hi from thread ##{i}` }
end
threads.each do |t|
  puts t.value
end

При запуске это производит:

Hi from thread #1
Hi from thread #2
Hi from thread #3
Hi from thread #4
Hi from thread #5

Ответ 3

Это простой и интересный способ использования значения Thread #:

a, b, c = [
  Thread.new { "something" },
  Thread.new { "something else" },
  Thread.new { "what?" }
].map(&:value)

a # => "something"
b # => "something else"
c # => "what?"

Ответ 4

Просто используйте Thread#value:

threads = (1..5).collect do |i|
  Thread.new { `echo x#{i}.bin` }
end
threads.each do |t|
  puts t.value
end

Ответ 5

Вы должны использовать класс Queue. Каждый поток должен поместить свой результат в очередь, и основной поток должен извлечь его оттуда. Обратите внимание, что используя этот подход, результат мой будет в порядке, отличном от порядка создания потоков в очереди.