Search code examples
pythonmultithreadingcherrypy

CherryPy waits for extra thread to end that is stopped later


I am building a application that uses CherryPy to serve a REST API, and another thread that does background work (in fact, it reads data from a serial port).

import cherrypy
import threading

class main:
    @cherrypy.expose
    def index(self):
        return "Hello World."

def run():
   while running == True:
       # read data from serial port and store in a variable

running = True
t = threading.Thread(target = run)
t.start()

if __name__ == '__main__':
    cherrypy.quickstart(main())

running = False

Both api.pc_main() and run work fine. The trouble is, I use a running boolean to stop my thread, but that piece of code is never reached, because CherryPy waits for that thread to finish when I push Ctrl-C. I actually have to use kill -9 to stop the process.


Solution

  • I fixed it by making my thread a CherryPy plugin. I used the code found here: Why is CTRL-C not captured and signal_handler called?

    from cherrypy.process.plugins import SimplePlugin
    
    class myplugin(SimplePlugin):
        running = False
        thread = None
    
        def __init__(self, bus):
            SimplePlugin.__init__(self, bus)
    
        def start(self):
            print "Starting thread."
            self.running = True
            if not self.thread:
                self.thread = threading.Thread(target = self.run)
                self.thread.start()
    
        def stop(self):
            print "Stopping thread."
            self.running = False
    
            if self.thread:
                self.thread.join()
                self.thread = None
    
    
        def run(self):
            while self.running == True:
                print "Thread runs."
                time.sleep(1)
    

    then in the main script:

    if __name__ == '__main__':
        mythread(cherrypy.engine).subscribe()
        cherrypy.quickstart(main())