Python Central HubSign in

Python Programming / Python Threading

Creating and Starting Threads

Create threads with threading.Thread, pass args, name threads, and wait for completion using join().

diagram start() runs it elsewhere; run() just calls it mermaid
Thread.run is the ordinary method holding your target. Calling it yourself executes the body on whatever thread you called it from, which means no concurrency at all and no error to tell you. start() is the one that asks the operating system for a thread and then invokes run there.

Basic Thread usage

Python
import threading
 
 
def greet(name: str) -> None:
    print("Hello", name)
 
 
t = threading.Thread(target=greet, args=("Ravi",))
t.start()
t.join()
print("Main thread finished")

Naming threads

Naming is helpful for logs.

Python
import threading
 
 
def work():
    print("Running in:", threading.current_thread().name)
 
 
t = threading.Thread(target=work, name="worker-1")
t.start()
t.join()

Common mistakes

1) Forgetting join()

If you don’t join(), the main program may exit early in some cases.

2) Sharing data without protection

Threads share memory. You need locks (next pages).

sketch start() puts the work elsewhere; run() does not p5.js
Two launches of the same target, which reports the thread it is executing on. With start() the work lands on a new thread and the main thread carries on immediately. With run() it is an ordinary method call, so the body executes on the caller and main waits for it -- no error, no warning, and no concurrency.

Check yourself

quizCheck yourself
  1. You call `t.run()` instead of `t.start()`. What happens?

    Show answer

    B — The target runs on the calling thread — no concurrency, no error — Verified by asking the target which thread it was on: `start()` reported `Thread-1`, `run()` reported `MainThread`. Nothing raises, so the program looks correct and is simply sequential.

  2. What does calling `start()` on a thread that has already finished do?

    Show answer

    C — Raises RuntimeError: threads can only be started once — Verified. A Thread object is single-use — create a new one per run.

  3. How do you reliably know a worker thread has finished?

    Show answer

    B — Call `t.join()`, then `t.is_alive()` is False — `join()` waits; `is_alive()` confirms. There is no `stop()` — a thread must be asked to finish, usually by checking a `threading.Event`.

  4. Why does threading often fail to speed up CPU-bound Python?

    Show answer

    B — The GIL lets only one thread run Python bytecode at a time — Measured elsewhere in this course: CPU-bound work on a 4-thread pool came out at 0.92x — slower than sequential. I/O-bound work on the same pool reached 9.2x, because a waiting thread releases the GIL.

🧪 Try It Yourself

Exercise 1 – Create a Simple Thread

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Exercise 2 – Join a Thread

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Exercise 3 – Run Multiple Threads

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Was this page helpful?

Let us know how we did