Какой самый простой способ напечатать вывод параллельных операций в Ruby, не мешая выводу? - PullRequest
11 голосов
/ 18 февраля 2011

Скажем, я разошелся с кучей потоков и хочу напечатать результаты выполнения каждого из них в STDERR.Как я могу сделать это таким образом, чтобы гарантировать, что выходные данные сохраняют строковую атомарность, то есть не перемешивают выходные данные из разных потоков в одной выходной строке?

# run this a few times and you'll see the problem
threads = []    
10.times do  
  threads << Thread.new do        
    puts "hello" * 40
  end     
end 
threads.each {|t| t.join}

1 Ответ

28 голосов
/ 18 февраля 2011

Put имеет условие гонки, поскольку он может записывать новую строку отдельно от строки.Вы можете увидеть этот шум, используя вставки в многопоточном приложении:

thread 0thread 1
thread 0thread 2
thread 1
thread 0thread 3
thread 2
thread 1

Вместо этого используйте print или printf

print "thread #{i}" + "\n"
print "thread #{i}\n"
printf "thread %d\n", i

Или, так как вы хотите писать в STDERR:

$stderr.print "thread #{i}\n"

Это ошибка в Ruby?Нет, если комментарии должны быть приняты в качестве стандарта.Вот определение IO.puts из MRI 1.8.7, хотя 2.2.2:

/*
 *  call-seq:
 *     ios.puts(obj, ...)    => nil
 *
 *  Writes the given objects to <em>ios</em> as with
 *  <code>IO#print</code>. Writes a record separator (typically a
 *  newline) after any that do not already end with a newline sequence.
 *  If called with an array argument, writes each element on a new line.
 *  If called without arguments, outputs a single record separator.
 *
 *     $stdout.puts("this", "is", "a", "test")
 *
 *  <em>produces:</em>
 *
 *     this
 *     is
 *     a
 *     test
 */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...