0

this is done in python 2.7.12

serialHelper is a class module arround python serial and this code does work nicely

#!/usr/bin/env python
import threading
from time import sleep
import serialHelper

sh = serialHelper.SerialHelper()

def serialGetter():
    h = 0
    while True:
        h = h + 1
        s_resp = sh.getResponse()
        print ('response ' + s_resp)
        sleep(3)

if __name__ == '__main__':
    try:
        t = threading.Thread(target=sh.serialReader)
        t.setDaemon(True)
        t.start()
        serialGetter()
        #tSR = threading.Thread(target=serialGetter)
        #tSR.setDaemon(True)
        #tSR.start()
    except Exception as e:
        print (e)

however the attemp to run serialGetter as thread as remarked it just dies. Any reason why that function can not run as thread ?

2
  • it just dies? how? python exits? message? Commented Dec 3, 2017 at 16:13
  • It dies. Because that's what setDaemon() is for. Commented Dec 3, 2017 at 16:35

1 Answer 1

2

Quoting from the Python documentation:

The entire Python program exits when no alive non-daemon threads are left.

So if you setDaemon(True) every new thread and then exit the main thread (by falling off the end of the script), the whole program will exit immediately. This kills all of the threads. Either don't use setDaemon(True), or don't exit the main thread without first calling join() on all of the threads you want to wait for.


Stepping back for a moment, it may help to think about the intended use case of a daemon thread. In Unix, a daemon is a process that runs in the background and (typically) serves requests or performs operations, either on behalf of remote clients over the network or local processes. The same basic idea applies to daemon threads:

  1. You launch the daemon thread with some kind of work queue.
  2. When you need some work done on the thread, you hand it a work object.
  3. When you want the result of that work, you use an event or a future to wait for it to complete.
  4. After requesting some work, you always eventually wait for it to complete, or perhaps cancel it (if your worker protocol supports cancellation).
  5. You don't have to clean up the daemon thread at program termination. It just quietly goes away when there are no other threads left.

The problem is step (4). If you forget about some work object, and exit the app without waiting for it to complete, the work may get interrupted. Daemon threads don't gracefully shut down, so you could leave the outside world in an inconsistent state (e.g. an incomplete database transaction, a file that never got closed, etc.). It's often better to use a regular thread, and replace step (5) with an explicit "Finish up your work and shut down" work object that the main thread hands to the worker thread before exiting. The worker thread then recognizes this object, stops waiting on the work queue, and terminates itself once it's no longer doing anything else. This is slightly more up-front work, but is much safer in the event that a work object is inadvertently abandoned.

Because of all of the above, I recommend not using daemon threads unless you have a strong reason for them.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks that is actually true...I believed it would be good enough to just run the deamon threads to keep the main thread alive. I keep it alive now with a while true sleep loop. Is there a more pythonic way ?
Either don't make them daemons, or call join as I explained.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.