Простейший код для воспроизведения этой проблемы:
t = Thread.new { Thread.stop }
t.join # => exception in `join': deadlock detected (fatal)
Thread :: stop → nil
Останавливает выполнение текущего потока, переводя его в «спящий» режим.
состояние и планирует выполнение другого потока.
Тема # присоединиться → thr
Тема # присоединение (ограничение) → thr
Вызывающий поток приостановит выполнение и запустит thr. Не возвращается
пока thr не выйдет или пока не пройдут лимитные секунды. Если срок
истекает, nil будет возвращено, иначе thr возвращается.
Насколько я понимаю, вы вызываете Thread.join
без параметров в потоке и ждете его завершения, но дочерний поток вызывает Thread.stop
и переходит в состояние sleep
. Это тупиковая ситуация, основной поток ожидает выхода дочернего потока, но дочерний поток спит и не отвечает.
Если вы вызываете join
с параметром limit
, то дочерний поток будет прерван по истечении времени ожидания, не вызывая взаимоблокировку вашей программы:
t = Thread.new { Thread.stop }
t.join 1 # => Process finished with exit code 0
Я бы порекомендовал выйти из ваших рабочих потоков после того, как они выполнят работу с Thread.exit
, или избавиться от бесконечного цикла и нормально дойти до конца потока выполнения, например:
if user_id == nil
raise StopIteration
end
#or
if user_id == nil
Thread.exit
end