Domanda

I have some Python code that creates a demon thread. The parent thread ends almost immediately, but the daemon thread keeps printing sleep.

import threading
import time
def int_sleep():
    for _ in range(1, 600):
        time.sleep(1)
        print("sleep")

def main():
    thread = threading.Thread(target=int_sleep)
    thread.daemon = True
    thread.start()
    time.sleep(2)
    print("main thread end...")

thread = threading.Thread(target=main)
thread.start()

sys.version:

'3.3.3 (v3.3.3:c3896275c0f6, Nov 18 2013, 21:19:30) [MSC v.1600 64 bit (AMD64)]'

Prints:

sleep

main thread end...

sleep

sleep

sleep

Why doesn't the Python daemon thread exit when parent thread exits?

È stato utile?

Soluzione

If you specify thread.daemon = True for your python thread, then the program will halt immediately when only the daemon is left. The the commands sent to stdout are lost.

Add this to a file called main.py

import threading
import time

def int_sleep():
  for _ in range(1, 600):
    time.sleep(1)
    print("sleep")

def main():
  thread = threading.Thread(target=int_sleep)
  thread.daemon = True
  thread.start()
  time.sleep(2)
  print("main thread end...")

thread = threading.Thread(target=main)
thread.daemon = True
thread.start()

Run it like this:

el@apollo:~/code/python/run01$ python --version
Python 2.7.6
el@apollo:~$ python main.py 
el@apollo:~$

See it prints nothing because the thread started. You set it to be a daemon and started it. Then the program ended.

Extra notes: If you paste this code into a python interpreter, all the print statements will appear on the terminal because the daemon never loses hold of its connection to stdout.

Read more: http://docs.python.org/2/library/threading.html

Altri suggerimenti

I can only reproduce the behavior described by OP (unending output of 'sleep') if done from the python shell. If run from a file it works as expected (a few lines of 'sleep' and a single line of 'main thread end ...' )

Similarly, the second program exits immediately if run as a file, BUT also prints unending 'sleep' statements when run from the python shell.

My conclusion: since the thread that is the python shell continues to run even after "main" finishes, preventing the daemon(s) from being terminated when run from the python shell.

Could this be considered a bug (i.e that Python's behavior is different depending on how the script is run) or is it expected ? I defer to more experienced Pythonistas...

BTW - tested with Python 3.2.3

For completeness check out this article. https://joeshaw.org/2009/02/24/605/

The monitoring was done inside a daemon thread. The Python docs say only:

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.

Which sounds pretty good, right? This thread is just occasionally grabbing some data, and we don’t need to do anything special when the program shuts down. Yeah, I remember when I used to believe in things too.

Despite a global interpreter lock that prevents Python from being truly concurrent anyway, there is a very real possibility that the daemon threads can still execute after the Python runtime has started its own tear-down process. One step of this process appears to be to set the values inside globals() to None, meaning that any module resolution results in an AttributeError attempting to dereference NoneType. Other variations on this cause TypeError to be thrown.

I'm not sure whether that's a bug that's been fixed or a bug still in existence or behaviour as per design. But if you see weirdness keep this in the back of your head.

So an alternative is to loop in the child thread on an exit flag which you can set in the main when you're done. Then wait in the main for the child thread to die and then clean up.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top