Search code examples
pythonpython-3.5python-multiprocessing

Properly terminate a process


I have a subclass of multiprocessing.Process and I want to terminate it correctly.

class MyProcess(Process):

    def __init__(self, target, input_queue, output_queue, database):
        super().__init__()
        self.input_queue = input_queue
        self.output_queue = output_queue
        self.target = target

        self.database = database
        self.db_session = database.create_session()
        # ...

    def run(self):
        signal.signal(signal.SIGINT, signal.SIG_IGN)
        while True:
            try:
                # doing some stuff here
            except Empty:
                break
            except Exception as err:
                logger.error(str(err))
        try:
            self.db_session.commit()
        except:
            logger.error(str(err))

I want to close self.db_session (which is an SQLAlchemy Session) when the process is terminated. But as the Python documentation says "exit handlers and finally clauses, etc., will not be executed". How can I correctly terminate a process and close the things it uses?


Solution

  • I found a nice solution, by using multiprocessing.Event(). I added an Event object to the constructor of my MyProcess class, and the process loop looks like that now:

    def run(self):
        while True:
            try:
                if self.stop_event.is_set():
                    break    # breaks the loop if a stop event is set
    
                # doing some stuff here
            except Empty:
                    break
            except Exception:
                logger.error(str(err))
    
        try:
            self.db_session.commit()
        except:
            logger.error(str(err))
    

    Instead of calling terminate() when I need to terminate my processes, I just call stop_event.set(), which will break the loop and close everything gracefully.