Threads in both
Four jobs that wait
Threads pay off when the work waits: a network response, a disk read, a sleep. Four jobs that each wait 0.2 seconds should finish in about 0.2 seconds when they run at the same time, in either language, because the waiting does not need the interpreter.
Ruby
threads = 4.times.map do
Thread.new { sleep 0.2 }
end
threads.each(&:join)
puts "4 threads, 0.2s of sleep each: done"
time ruby threads.rb
4 threads, 0.2s of sleep each: done real 0m0.315s user 0m0.081s sys 0m0.035s
Python
import threading import time def work(): time.sleep(0.2) threads = [threading.Thread(target=work) for _ in range(4)] for thread in threads: thread.start() for thread in threads: thread.join() print("4 threads, 0.2s of sleep each: done")
time python3 threads.py
4 threads, 0.2s of sleep each: done real 0m0.248s user 0m0.040s sys 0m0.010s
Both runs take about a quarter of a second: the four waits overlap. The total wall time is close to one wait, not four, which is the whole point of threads for I/O.
What differs
- The lock has a different name. CRuby runs Ruby code under the Global VM Lock (GVL); CPython under the Global Interpreter Lock (GIL). Neither runs two threads of pure computation at the same moment, so both scale on waiting, not on arithmetic.
- The API. Thread.new { ... } returns a thread that starts at once; threading.Thread needs a start() call. Both wait with join, and both ship a queue for passing work.
- Processes. For CPU work both languages reach for processes: Process.fork on Linux, multiprocessing in Python. Lesson 130 goes through the Ruby side.
- The numbers. The timings above are one run on one machine; a hundredth of a second between them says nothing about the languages.
What to watch for
A thread that raises an exception can end silently unless the program
joins it or sets abort_on_exception (Ruby) or
reads thread.exc_info (Python). Join every thread
you start, in both languages.
Do not reach for threads because they are there. A script that runs four
commands one after another is often clearer than a pool, and a pool that
writes to one file needs a lock in either language.
Next: The same task, measured
Article author: Arthur Isaev