2
votes

I am trying to understand daemon threads in Python. My understanding is that daemon threads are automatically killed once the main thread exits or non-daemonic threads are killed. However, on a Windows machine, that is not my observation.

import threading
import time


def print_work_a():
    print('Starting of thread :', threading.currentThread().name)
    time.sleep(2)
    print('Finishing of thread :', threading.currentThread().name)


def print_work_b():
    print('Starting of thread :', threading.currentThread().name)
    print('Finishing of thread :', threading.currentThread().name)

a = threading.Thread(target=print_work_a, name='Thread-a', daemon=True)
b = threading.Thread(target=print_work_b, name='Thread-b')

a.start()
b.start()

Output observed:

>>> Starting of thread :Thread-a
Starting of thread :Thread-b


Finishing of thread :Thread-b

Finishing of thread :Thread-a

I was expecting that the output wouldn't contain Finishing of thread :Thread-a since by that time the non-daemon thread would be killed and hence the daemon thread would also be killed. What is the mistake in the code that is causing the daemon thread to remain alive?

2

2 Answers

3
votes

From the docs:

A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left.

The issue with daemon threads is when ran from shell (or an IDE) for example, the shell itself is the main thread! So the daemon thread will live as long as the shell lives and will get to finish execution. I am guessing that this is your case.

Try running your script through cmd and your expected output will appear. Meaning, thread-a will not finish. After copying your code to a .py file, I ran it through the basic python shell (IDLE) and got:

>>> Starting of thread :Starting of thread :  Thread-aThread-b

Finishing of thread : Thread-b
Finishing of thread : Thread-a

Image showing the above result in Python IDLE

But, when run through the cmd, I got:

Starting of thread : Thread-a
Starting of thread : Thread-b
Finishing of thread : Thread-b

Image showing the above result given by running in the terminal

0
votes

I can't help but notice a >>> in your output. Are you running/importing this in an interactive interpreter? If so, the interactive interpreter would still be running, so the daemon thread has plenty of time to exit unless you kill the interactive interpreter within two seconds. You need to run this as a standalone script from the regular OS shell (e.g. cmd.exe on Windows, bash or similar on UNIX-like systems, etc.).