Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Gracefully handling keyboard interrupt for Python multi-processing

I am working on a project which runs two separate python processes. When I do a ctrl + c to end the program, I would like the program to end gracefully.

I can produce a minimum working version of the code through the following:

from multiprocessing import Process

import os
import sys
import time


class Test:
    def __init__(self):
        pass

    def run(self):
        self.process_a = Process(target=self.main, daemon=True)
        self.process_b = Process(target=self.other_func, daemon=True)
        self.process_a.start()
        self.process_b.start()
        self.process_a.join()
        self.process_b.join()


    def main(self):
        try:
            while True:
                print('sending stuff...')
                time.sleep(5)
        except KeyboardInterrupt:
            self.shutdown()

    def other_func(self):
        while True:
            print("do other stuff...")
            time.sleep(5)

    def shutdown(self):
        print("\nCTRL+C pressed ...")
        print("Shutting Down...")
        
        # os._exit(1)
        
if __name__ == '__main__':
    mytest = Test()
    mytest.run()

When performing a keyboard interrupt, I get the error after it prints Shutting Down...:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Traceback (most recent call last):
  File "testing-error.py", line 47, in <module>
    mytest.run()
  File "testing-error.py", line 18, in run
    self.process_a.join()
  File "/usr/lib/python3.8/multiprocessing/process.py", line 149, in join
    res = self._popen.wait(timeout)
  File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 47, in wait
    return self.poll(os.WNOHANG if timeout == 0.0 else 0)
  File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 27, in poll
    pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt

In fact, I can further reduce the code down to the following and get the same error:

from multiprocessing import Process

import os
import sys
import time


class Test:
    def __init__(self):
        pass

    def run(self):
        self.process_a = Process(target=self.main, daemon=True)
        self.process_a.start()
        self.process_a.join()

    def main(self):
        try:
            while True:
                print('sending stuff...')
                time.sleep(5)
        except KeyboardInterrupt:
            self.shutdown()


    def shutdown(self):
        print("\nCTRL+C pressed ...")
        print("Shutting Down...")
        
        # os._exit(1)
        
if __name__ == '__main__':
    mytest = Test()
    mytest.run()

Can anyone help me understand what’s going wrong?

>Solution :

Both processes are getting CTRL-C so both need to catch it:

import multiprocessing as mp

import os
import sys
import time


class Test:
    def __init__(self):
        pass

    def run(self):
        self.process_a = mp.Process(target=self.main, daemon=True)
        self.process_a.start()
        try:
            self.process_a.join()
        except KeyboardInterrupt:
            print(mp.current_process().name,'got CTRL-C')

    def main(self):
        try:
            while True:
                print('sending stuff...')
                time.sleep(5)
        except KeyboardInterrupt:
            print(mp.current_process().name,'got CTRL-C')

if __name__ == '__main__':
    mytest = Test()
    mytest.run()

Output:

sending stuff...
Process-1 got CTRL-C
MainProcess got CTRL-C
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading