pythonmultithreadingpython-daemon

python-daemon - running thread inside


I'm using python-daemon, but I have a thread inside the daemon to check a serial port occasionally:

context = daemon.DaemonContext(pidfile=daemon.pidfile.TimeoutPIDLockFile('/var/run/gpstemp.pid'),
                          uid = 0,
                          gid = 4,
                          umask = 0o002,
                          stdout = sys.stdout,  # change these for deployment
                          stderr =sys.stderr,   # change these for deployment
                          chroot_directory= None,
                          working_directory='/home/debian/gpstemp'
app = App()
with context:
    app.run()

The thread runs this:

class App():
    def __init__(self, port = 5556):
    ...
        # Handle all those threading things
        self.__sem = Lock()
        self.interval = 60.0  # interval between time updates in seconds
        self.worker = Thread(target = self._get_datetime_worker)
    def run(self):
        self.worker.start()
...
    def _get_datetime_worker(self):
        while not self.exit.is_set():
            self._get_datetime()
            self.exit.wait(self.interval)

I'm using systemctl to start and stop it using a .service file. When I run: sudo systemctl stop myservice

It waits 60 seconds before returning. How would I kill my thread in the service immediately through systemctl. I considered passing the context to the App and then redefining:

 context.signal_map = {
     signal.SIGTERM: app.shutdown,
     signal.SIGHUP: app.shutdown,
     }

and then adding a shutdown method to App that does:

def shutdown(self, *args):
    self.exit.set()
    self.worker.join()

But, that doesn't let the context destroy the PID and doesn't exit the context right. What else should I add to the shutdown method to make things work correctly?

Kurt


Solution

  • Do I understand it correctly that you want to kill the thread as well when you kill your main program? You can do this by setting daemon=True:

    def run(self):
        self.worker.daemon = True
        self.worker.start()