liveBook · Manning

Thread

As explained in The Well-Grounded Rubyist, Fourth Edition

Thread is Ruby's class for creating and controlling threads of execution.

Use a thread when one part of a Ruby program must keep working while another waits. A server, for example, can keep accepting connections while a client takes time to answer a question. `Thread.new` takes a block and starts running it immediately; the code after `Thread.new` continues too. Execution is concurrent, but not necessarily parallel: how threads share time depends on the Ruby implementation and the system, and Ruby’s Global VM Lock can prevent simultaneous execution. section 14.5 section 14.5.2

Wait for the work to finish

A thread that sleeps for a second does not make the surrounding code sleep. Without a further wait, the program can end before the thread prints its final message, killing the still-running thread. Keep the returned `Thread` object and call `join` when the main code must wait for completion. section 14.5

t = Thread.new do
  puts "Starting the thread"
  sleep 1
  puts "At the end of the thread"
end
puts "Outside the thread"
t.join

Run this listing with and without `t.join` to see why starting a thread and waiting for it are separate actions. section 14.5

For a server handling multiple clients, place `Thread.new` inside the accept loop. Pass each accepted connection to `Thread.new(conn) do |c| ... end`: the argument becomes the block parameter, giving that thread its own connection reference rather than making threads contend over the outer `conn` variable. While one thread waits at `c.gets`, the server can accept another client. section 14.5.2

Thread objects also let you control execution and inspect its state:

  • Call `join` to wait; use `wakeup` or `run` to resume a stopped thread. Check `status`, `stop?`, or `alive?` when its state matters. section 14.5 section 14.5.1
  • Call `kill`, `exit`, or `terminate` to end a thread. Code running inside a thread can call `Thread.exit`, as when a file-reading task cannot find a required file. section 14.5.1

A thread’s block can access local variables from its surrounding scope, and changes to those variables persist. Most globals are shared too, but regular-expression capture globals such as `$1` are thread-local, so one thread’s match does not replace another’s capture. A thread can also store values under symbol or string keys, such as `my_thread[:message] = "Hello"`. Distinguish threads from fibers: a fiber resumes and yields at explicit points, whereas thread scheduling is not controlled by those yield points. section 14.5.4 section 14.7 section 14.5.1

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Works through creation, joining, lifecycle control, state checks, and variable behavior while leaving native-versus-green threading internals black-boxed.
Examples
Uses a sleeping thread, a missing-file task, and a date server whose clients can pause before replying.
What it assumes
Assumes familiarity with Ruby blocks and local variables, while introducing thread creation through a small executable example.
What you can do after
Build it from scratch: start and join Ruby threads, then give each server connection its own thread.
How it connects
Connects threads to code blocks, TCP servers, variable scope, regular-expression captures, and fibers.

Also explained in

Compare how 12 books explain thread →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Rubyist, Fourth Edition. The section links point to the parts of the book it draws on.