Ruby の GVL(Giant VM Lock)について復習した。

コードサンプル

例えば下記のコードはスレッドで実行しているが、Ruby内部でGVLが働き、必ず結果は10になる(シリアルに実行される)。

counter = 0
10.times.map do
  Thread.new do
    temp = counter + 1
    counter = temp
  end
end.each(&:join)
puts counter #=> 10

IO GVL 解放

ただ例外としてIO操作を行うときはGVLを一時的に解放する。

IO 関連のブロックする可能性があるシステムコールを行う場合には GVL を解放します。

ref. スレッド (Ruby 3.4 リファレンスマニュアル)

例えば下記のコードは途中にIO処理を挟み込むと、スレッド処理途中でGVLが解放され、結果は1になる。

counter = 0
10.times.map do
  Thread.new do
    temp = counter + 1
    puts nil
    counter = temp
  end
end.each(&:join)
puts counter #=> 1

Working With Ruby Threads

詳しくは下記の Working With Ruby Threads を読んでみるとよい。

The GIL and MRI - Working With…

see also. 2024-07-23 Working With Unix Processes / Working With TCP Sockets / Working With Ruby Threads | TTIL

参考