LoginSignup
3
0

More than 5 years have passed since last update.

Parallel 的ゾンビを殺した話

Last updated at Posted at 2019-03-26

TL; DR

v1.16.0 から、 parallel の gem 使ってるときに timeout とか使って親を殺しても、ちゃんと子供達も kill されるようになりました。

詳細

parallel の gem は、便利なんだけれども、親スレッドを kill してもその子供達は普通に活動し続ける。 thread であろうとも process であろうとも。

例:

t = Thread.new do
  Parallel.map(0..1000, in_threads: 2) do |i|
    p i
    sleep 1
  end
end
sleep 1
t.kill
sleep
# 0 
# 1                                   
# 3                               
# 2                         
# 5
# 4
# => kill しているにも関わらず 1000 まで出力される。      

たとえば、悪名高い timeout と組み合わせるとこうなる。

begin
  Timeout.timeout(1) do
    Parallel.map(0..1000, in_threads: 2) do |i|
      p i
      sleep 1
    end
  end
rescue Timeout::Error
  p :timeout
end
sleep
# 0
# 1
# 2
# 3
# :timeout
# 4
# 5
# 6
# 7
# 8
# => 1000 まで続く

これは、あんまりにもあれなので、 parallel 本家に以下の PR を出してマージしてもらった。

これによって、 Timeout やら 親スレッドの kill やらが行われた時に、その子供のスレッドやプロセスについても正しく kill されるようになった。

begin
  Timeout.timeout(1) do
    Parallel.map(0..1000, in_threads: 2) do |i|
      p i
      sleep 1
    end
  end
rescue Timeout::Error
  p :timeout
end
sleep
# 0
# 1
# 3
# :timeout
# 2
# => ここでとまる

Concurrent Ruby を使えよ、という話は若干ある

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0