Edited at

puts "hoge" と print "hoge\n" のちょっとした違い

More than 1 year has passed since last update.

puts "hoge"print "hoge\n"は普通、同じ動きをしますが、マルチスレッドのときは少し違うようです。

# ruby 2.4.1p111

THREAD_NUM = 3

Array.new(THREAD_NUM) do
Thread.new do
10.times do
puts "hoge"
end
end
end.each(&:join)

puts "-"*5

Array.new(THREAD_NUM) do
Thread.new do
10.times do
print "hoge\n"
end
end
end.each(&:join)

これを実行すると

[] % ruby sample.rb

hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hogehoge

hoge
hoge
hoge
hoge
hoge
hoge
-----
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge
hoge

putsはスレッドセーフでは無いようで、文字列を出力したあと、改行する前に別のスレッドが割り込んでしまうことがあります。

あんまりないと思いますが、rubyでマルチスレッドコードを書くときはお気をつけて。


追記

ruby 2.5.0 では再現しないっぽいです。


2018/06/04 追記

stackoverflowにて、密かに尊敬する @raccy さんから詳しい解説を頂きました。

この場を借りて感謝を申し上げます。