1

I'm using multiprocessing on Python 3.6 on Ubuntu to handle the faster communication with another device.

I set daemon = True to terminate the child process when the parent process finishes. However, when the main process is terminated, the another process (_another_process in the following code) sometimes isn't terminated and continues to be alive. Then, when I run the same program again, I get address already in use error when I run the above code. Of course, I can kill this process, but it's annoying and I'd like to solve.

Class Xxx
 def __init__(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.settimeout(2.5)
        self.sock.bind((self.ip, self.port))
        self.sock.settimeout(None)    
        self.start_process()
        time.sleep(1.5)

    def start_process(self):      
        p = mp.Process(target=self._another_process)
        time.sleep(1)
        p.daemon = True
        p.start()

    def _another_process(self):
        while True:
            # Do continuous (infinite) operation

I don't know why sometimes terminated and sometimes not, but are there any better implementations to realize what I want? Or, is daemon = True the best way?

I believe I shouldn't use join() because my child process has an infinite operation, but if I misunderstood, please let me know.

kangaroo
  • 407
  • 4
  • 19
  • Thank you. I already got two solutions but not sure which is better. Is it safe to use SO_REUSEADDR? Is main destructor called whenever terminate the process? – kangaroo Mar 04 '17 at 18:29

2 Answers2

2

From the python3 docs, process.terminate() in the main's destructor:

p.start() print(p, p.is_alive()) p.terminate()

This will send SIGTERM to be handled by the child process. alternatively, use p.kill() to send SIGKILL.

Full example at https://docs.python.org/3/library/multiprocessing.html

For how to handle SIGTERM in your application: How to process SIGTERM signal gracefully?

Community
  • 1
  • 1
  • Thank you. I'd use this. Are there any downside or potential issues to use this? – kangaroo Mar 06 '17 at 17:55
  • Well you should be aware that it does not force the child process to terminate, but rather send unix signal SIGTERM that can be caught, ignored, or handled in any way by the child process. – a_at_cyber_dot_training Mar 06 '17 at 19:19
  • I create destructor (I replace `p` to `self.process`) and run terminate(), but it still runs. The result of `print(self.process, self.process.is_alive())` is `` – kangaroo Mar 06 '17 at 19:22
  • I would suggest either SIGKILL that that cannot be caught - instead of `terminate()` use `kill()` or otherwise catch the SIGTERM inside your child process and exit gracefully. http://stackoverflow.com/questions/18499497/how-to-process-sigterm-signal-gracefully – a_at_cyber_dot_training Mar 06 '17 at 19:33
  • Thanks. I tried to use graceful exit, but whenever SIGTERM is called, the child process pauses its process, therefore, cannot exit gracefully by using flags. – kangaroo Mar 06 '17 at 22:37
  • Is this what you expected? If so, the only choice is to use `kill()`. – kangaroo Mar 06 '17 at 22:38
  • Or maybe I shouldn't use daemon=True? – kangaroo Mar 06 '17 at 23:18
  • You have two choices, use `kill()` or debug the child to figure what's blocking it from terminating. I'd go for reducing the code until I find out then post a new question. – a_at_cyber_dot_training Mar 06 '17 at 23:28
  • Thanks, I used kill() because terminate() didn't work in this case. – kangaroo Mar 07 '17 at 02:52
  • I edited my answer in accordance to this discussion. – a_at_cyber_dot_training Mar 07 '17 at 07:11
0

To solve the "address already in use" problem, try adding the SO_REUSEADDR socket option.

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485