Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python daemon threads and the "with" statement

If I have the following code in a daemon thread and the main thread does not do invoke a join on the daemon. Will the file close safely since it is used inside "with" once the main thread exits or no? Anyway to make it safe? Thanks :D

while True:
    with open('file.txt', 'r') as f:
        cfg = f.readlines()
time.sleep(60)
like image 655
Sam Thomas Avatar asked Jun 06 '17 18:06

Sam Thomas


People also ask

What is daemon thread in Python?

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 initial value is inherited from the creating thread. The flag can be set through the daemon property or the daemon constructor argument.

What is Daemonic Python?

daemon-This property that is set on a python thread object makes a thread daemonic. A daemon thread does not block the main thread from exiting and continues to run in the background. In the below example, the print statements from the daemon thread will not printed to the console as the main thread exits.

How would you execute functions in a separate new thread with the module thread?

First, we must create a new instance of the threading. Thread class and specify the function we wish to execute in a new thread via the “target” argument. The function executed in another thread may have arguments in which case they can be specified as a tuple and passed to the “args” argument of the threading.


1 Answers

From the docs:

Note: Daemon threads are abruptly stopped at shutdown. Their resources (such as open files, database transactions, etc.) may not be released properly. If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event.

This suggests, but does not outright state, that daemon threads are terminated without a chance for __exit__ methods and finally blocks to run. We can run an experiment to verify that this is the case:

import contextlib
import threading
import time

@contextlib.contextmanager
def cm():
    try:
        yield
    finally:
        print 'in __exit__'

def f():
    with cm():
        print 'in with block'
        event.set()
        time.sleep(10)

event = threading.Event()

t = threading.Thread(target=f)
t.daemon = True
t.start()

event.wait()

where we start a daemon thread and leave it sleeping in a with block when the main thread exits. When we run the experiment, we get an output of

in with block

but no in __exit__, so the __exit__ method never gets a chance to run.


If you want cleanup, don't use a daemon thread. Use a regular thread, and tell it to shut down at the end of the main thread through the regular inter-thread communication channels.

like image 188
user2357112 supports Monica Avatar answered Oct 16 '22 15:10

user2357112 supports Monica