flowchart TD
A["main thread finishes"] --> B{"any non-daemon threads still running?"}
B -->|yes| C["the process waits for them"]
C --> D["they run to completion"]
B -->|no| E["the interpreter shuts down"]
E --> F["daemon threads are killed mid-statement"]
F --> G["no finally, no cleanup, no flush"]
G --> H["a half-written file, a held lock, a lost record"]
D --> I["use non-daemon + join() for work that must complete"]
F --> J["use daemon only for work that is safe to abandon"]
What is a daemon thread?
A daemon thread is a background thread.
- If only daemon threads are left running, Python can exit.
- Non-daemon threads keep the program alive.
Example
import threading
import time
def background():
while True:
print("background working...")
time.sleep(0.5)
t = threading.Thread(target=background, daemon=True)
t.start()
time.sleep(2)
print("Main thread exiting")When to use daemon threads
- logging/reporting loops
- background monitoring
When NOT to use them
Don’t use daemon threads for work that must finish (e.g., writing critical data).
Check yourself
A daemon thread is halfway through writing a file when the main thread finishes. What happens?
Measured: the same worker printed FINISHED with `daemon=False` and printed nothing with `daemon=True`. Interpreter shutdown does not ask daemon threads to stop; it stops existing.
Show answer
B — It is killed where it stands — no exception, no `finally`, no flush — Measured: the same worker printed FINISHED with `daemon=False` and printed nothing with `daemon=True`. Interpreter shutdown does not ask daemon threads to stop; it stops existing.
When is a daemon thread the right choice?
A heartbeat, a metrics poller or a cache warmer can be abandoned safely. Anything holding a lock, writing a file, or with a record in flight cannot.
Show answer
B — When abandoning the work half-done is harmless — A heartbeat, a metrics poller or a cache warmer can be abandoned safely. Anything holding a lock, writing a file, or with a record in flight cannot.
How do you make sure a worker thread finishes before the program exits?
A non-daemon thread keeps the process alive by itself; `join()` makes the wait explicit. There is no `stop()` — a thread must be asked to finish, usually via a `threading.Event` it checks.
Show answer
B — Leave it non-daemon (the default) and `join()` it — A non-daemon thread keeps the process alive by itself; `join()` makes the wait explicit. There is no `stop()` — a thread must be asked to finish, usually via a `threading.Event` it checks.
What is the cleanest way to tell a long-running thread to shut down?
Cooperative shutdown is the only reliable kind. The thread checks the flag at a point where stopping is safe, then unwinds normally — running its `finally` blocks.
Show answer
B — Give it a `threading.Event` it checks periodically — Cooperative shutdown is the only reliable kind. The thread checks the flag at a point where stopping is safe, then unwinds normally — running its `finally` blocks.
🧪 Try It Yourself
Exercise 1 – Create a Daemon Thread
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 2 – Non-Daemon vs Daemon
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 3 – Main Thread is Not a Daemon
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.