Thread#status and the thread lifecycle
What you already know, in two sentences
The lesson "Threads and concurrency", in the intern course Operating system basics, covered process against thread and concurrency against parallelism. It also covered the GVL and why it's released during I/O, Thread.new/.join, a race-condition demo fixed with Mutex#synchronize, and Puma's model of several processes with several threads each. None of that is repeated here. This course assumes you know threads exist, why Ruby uses them despite the GVL, and that Mutex prevents races. Its seven lessons cover what happens when a thread hangs, two locks deadlocking, and checking the I/O claim with a stopwatch instead of a diagram.
A thread has a status you can inspect
t = Thread.new { sleep 0.3 }
sleep 0.05
t.status
# "sleep"
t.alive?
# true
t.join
t.status
# false
t.alive?
# false
Thread#status returns a String, not a symbol, while a thread is doing something Ruby can name: "sleep" here, since the thread is blocked in sleep. A thread doing ordinary work reports "run". Once a thread finishes normally, status returns false instead of a string, and alive? becomes false too.
Three endings, different values
A thread can stop for three reasons, and status reports them like this:
# Finished normally
t1 = Thread.new { 1 + 1 }
t1.join
t1.status
# false
# Died from an unhandled exception
t2 = Thread.new { raise "boom" }
sleep 0.1
t2.status
# nil
# Killed explicitly
t3 = Thread.new { sleep 1 }
t3.kill
sleep 0.05
t3.status
# false
false means "ended without an exception". nil means "ended because of an unhandled exception". That difference lets code tell a thread that finished its work from one that crashed by reading status, without wrapping every thread in begin/rescue.
kill looks like a normal ending
Thread#kill (with Thread#exit and Thread#terminate as aliases) stops a thread from outside, and status reports it as a normal finish: false, with no separate "killed" value. If some logic needs to tell "finished on its own" from "killed by other code", it has to track that separately, because status alone can't say which happened.
Why this matters for the rest of the course
Every remaining lesson, the deadlock demo, the queue examples and the benchmarks, needs to answer "is this thread still doing something, and if not, how did it stop?" without guessing. status and alive? answer that from outside the thread. The next lesson's deadlock demo relies on them to show that two threads never finished, instead of inferring it from a hung terminal.
Key takeaways
Thread#statusreturns a string like"sleep"or"run"while a thread is active.- A thread that finished normally or was
.killed reportsfalse; a thread that died from an unhandled exception reportsnil. Thread#alive?is a simple boolean:truefor a thread that hasn't stopped.statusalone can't tell "finished on its own" from "killed by other code": both reportfalse.
Keep going with lesson 2
abort_on_exception and report_on_exception
How report_on_exception logs a thread's unhandled exception and abort_on_exception raises it again in the main thread.
A free account also gives you the quizzes, your progress and notes, and the discussion.