Jon
Jon

Reputation: 2567

Python Multiprocessing Set Timeout and Terminate

I am using multiprocessing to spawn individual processes of a task. If the task takes longer than 5 seconds, I would like the processes to be killed. In the documentation, it states the following

join([timeout])

If the optional argument timeout is None (the default), the method blocks until the process whose join() method is called terminates. If timeout is a positive number, it blocks at most timeout seconds...

However, in testing using the code below, I notice that the process is not killed after the set 5 seconds.

import time
import multiprocessing as mp
from random import randint, seed
import os


def task(i):
    x = randint(0, 20)
    pid = os.getpid()
    print("{}. (PID: {}) sleeping for {} seconds".format(i, pid, x))
    time.sleep(x)
    print("{}. (PID: {}) slept for {} seconds".format(i, pid, x))




if __name__ == '__main__':
    ctx = mp.get_context() # use system default
    for i in range(10):
        seed(i) # set random state
        p = ctx.Process(target = task, args = (i,))
        p.start()
        p.join(5) # terminate after 5 seconds

Am I misunderstanding the usage of this parameter? Is there another method to get the intended result?

Results

0. (PID: 12568) sleeping for 4 seconds
0. (PID: 12568) slept for 4 seconds
1. (PID: 6396) sleeping for 18 seconds
2. (PID: 8520) sleeping for 9 seconds
3. (PID: 11192) sleeping for 14 seconds
2. (PID: 8520) slept for 9 seconds
4. (PID: 9336) sleeping for 9 seconds
1. (PID: 6396) slept for 18 seconds
5. (PID: 596) sleeping for 4 seconds
3. (PID: 11192) slept for 14 seconds
5. (PID: 596) slept for 4 seconds
4. (PID: 9336) slept for 9 seconds
6. (PID: 2920) sleeping for 4 seconds
6. (PID: 2920) slept for 4 seconds
7. (PID: 11128) sleeping for 14 seconds
8. (PID: 14164) sleeping for 14 seconds
9. (PID: 9332) sleeping for 9 seconds
7. (PID: 11128) slept for 14 seconds
8. (PID: 14164) slept for 14 seconds
9. (PID: 9332) slept for 9 seconds

Upvotes: 0

Views: 263

Answers (1)

Carles Sala
Carles Sala

Reputation: 2109

As you noticed, the p.join is not terminating the child process after the timeout, only blocking for the specified time (at most) and then continuing his flow without waiting any more for the child process.

If you want them killed after the timeout, all you need to do is to explicitly call terminate() on the process:

p.join(5)
p.terminate()

Upvotes: 1

Related Questions