Python 多处理设置超时并终止

Python Multiprocessing Set Timeout and Terminate

我正在使用 multiprocessing 生成 task 的各个进程。如果 task 花费的时间超过 5 秒,我希望进程被终止。在documentation中,它声明了以下内容

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...

但是,在使用下面的代码进行测试时,我注意到进程在设定的 5 秒后没有被终止。

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

我是不是误解了这个参数的用法?是否有其他方法可以获得预期结果?

结果

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

如您所见,p.join 不会在超时后终止子进程,只会阻塞指定的时间(最多),然后继续他的流程而不再等待子进程。

如果你想让它们在超时后被杀死,你需要做的就是在进程上显式调用terminate()

p.join(5)
p.terminate()