Как я могу убить поток ruby через определенное время?

#ruby #multithreading

#ruby #многопоточность

Вопрос:

Я хочу, чтобы поток, который я создаю, умер, если он не завершится через определенное время. Есть ли какой-нибудь элегантный и / или идиоматический способ сделать это? Прямо сейчас я подумываю о создании потока наблюдателей:

 def myfunc
  t = Thread.new{
    #do stuff
  }

  # watcher thread
  Thread.new{
    result = t.join(20) # join returns nil if it timed out
    t.kill if result.nil?
  }

  # continue on asynchronously from both threads
end
  

Ответ №1:

Возможно, класс Timeout — это то, что вам нужно.

 def myfunc
  Thread.new{
    Timeout::timeout(20) {
      #do stuff
    }
  }

  # continue on asynchronously
end
  

Комментарии:

1. ах, ха, отлично! я отредактировал ваш ответ, чтобы включить пример того, как использовать его для решения проблемы…

2. Я думаю, вам не нужно переносить объект Timeout внутри потока. Тайм-аут создает поток для блока кода, поэтому вам не нужно, если вы не хотите, чтобы все это было асинхронным.

3. Да, я хочу, чтобы он был асинхронным — в этом весь смысл, я хочу, чтобы поток очистился, если он застрял.

Ответ №2:

Я считаю, что в большинстве случаев вы должны контролировать «жизнь» потока с помощью программной логики в потоке.

Предположим, что поток на самом деле представляет собой бесконечный цикл, вместо простого while(true) у вас может быть переменная экземпляра (например, is_running ) и сделать цикл чем-то вроде while(is_running). Если другой поток хочет остановить этот поток, они могут просто (прямо или косвенно) сделать is_running ложным. Затем рабочий поток может завершить последнюю часть работы и завершить цикл.

Комментарии:

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