Короткий ответ
Daemon-поток автоматически прерывается при завершении основной программы, не дожидаясь своего окончания, тогда как обычный поток удерживает процесс от завершения, пока сам не закончит работу — это удобно для фоновых задач, но рискует прервать работу без корректной очистки.
Как это работает подробнее
Атрибут daemon=True устанавливается до вызова start(); интерпретатор не ждёт завершения daemon-потоков при выходе из программы, в отличие от обычных потоков, которые нужно явно join() или программа будет ждать их завершения перед выходом.
Пример кода
example-278.py
import threading, time
def background_cleanup():
while True:
time.sleep(1)
print("фоновая очистка кэша...")
t = threading.Thread(target=background_cleanup, daemon=True)
t.start()
time.sleep(2)
print("основная программа завершается")
# Проверка: процесс завершится сразу после print, не дожидаясь background_cleanup,
# daemon-поток будет прерван без возможности завершить текущую итерацию цикла корректноЧто использовать на практике
- Практика. Daemon-потоки удобны для фоновых служебных задач (периодическая очистка кэша, heartbeat), которые не критичны для корректности данных; для задач, критичных для целостности данных (запись в файл, коммит транзакции), daemon-поток рискован, так как может быть прерван посередине операции.
Подводные камни
- Риски. Делают daemon-потоком задачу, которая должна гарантированно завершить запись данных перед выходом процесса, и теряют данные при штатном завершении приложения; ожидают, что daemon-поток получит шанс на graceful shutdown — по умолчанию он просто прерывается без вызова кода очистки.