多进程:进程池、映射和sys.exit()

5

我认为我需要一些建议。下面是我的代码:

from multiprocessing import Pool
import time
import sys

def testing(number):
    count = 0
    while True:
        print('Count: {}'.format(count))
        count += 1

        if count > number:
            print('Exiting...')
            sys.exit()
        else:
            print('Looping Over')
            time.sleep(1)

if __name__ == '__main__':

    with Pool(2) as p:
        p.map(testing, [3, 2])

期望的结果:

一旦所有子线程退出,程序(主线程)应该退出。

实际结果:

$ python3 test_exit.py
Count: 0
Looping Over
Count: 0
Looping Over
Count: 1
Looping Over
Count: 1
Looping Over
Count: 2
Looping Over
Count: 2
Exiting...   <<< Exited 1st thread.
Count: 3
Exiting...   <<< Exited 2nd thread.
....and it stays here as if stuck or something. It never gives control back to Shell.

期望结果:

$ python3 test_exit.py
Count: 0
Looping Over
Count: 0
Looping Over
Count: 1
Looping Over
Count: 1
Looping Over
Count: 2
Looping Over
Count: 2
Exiting...
Count: 3
Exiting...
$   <<< Note: I am expecting to be dropped back to Shell prompt

问题:

我的连接池/映射使用方法有什么问题吗?

3个回答

3

一旦所有子线程退出,程序(主线程)应该退出。

  • 通过在关键循环中使用break语句来完成进程并终止其目标函数testing()
  • 当进程池完成时,退出主线程/程序。

from multiprocessing import Pool, current_process
import time
import sys

def testing(number):
    count = 0
    while True:
        print('Count: {}'.format(count))
        count += 1

        if count > number:
            print('Exiting...', current_process().name)
            break
        else:
            print('Looping Over')
            time.sleep(1)

if __name__ == '__main__':

    with Pool(2) as p:
        p.map(testing, [3, 2])
    sys.exit()

最终输出:
Count: 0
Looping Over
Count: 0
Looping Over
Count: 1
Looping Over
Count: 1
Looping Over
Count: 2
Looping Over
Count: 2
Exiting... ForkPoolWorker-2
Count: 3
Exiting... ForkPoolWorker-1
$

2

这种行为的解释:

发生这种情况是因为当您调用 sys.exit() 时,它会引发 systemExit 异常。由于 sys.exit() 最终只会引发异常,因此它仅退出调用它的进程,并且不会向上级主进程传播。

一旦所有子进程退出,主进程就会坐在那里等待从子进程返回的内容。所有子进程已经退出,因此没有内容可返回,导致永远等待。

注:Original Answer 翻译成“最初的回答”。


0
尝试使用 os._exit(1) 而不是 sys.exit();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接