【问题标题】:Multiprocessing: pool and map and sys.exit()多处理:池和映射以及 sys.exit()
【发布时间】:2019-06-21 15:51:25
【问题描述】:

我想我需要一些建议。以下是我的代码:

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

问题:

就池/地图使用而言,我的方法有什么问题吗?

【问题讨论】:

    标签: python multiprocessing


    【解决方案1】:

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

    • 通过终止其目标函数testing() 来完成一个进程(通过关键循环中的break 语句完成)
    • 进程池完成后退出主线程/程序。

    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 Exception。因为sys.exit() 最终只会引发一个异常,它只会退出被调用的进程并且不会被传播进一步到主要流程。

      一旦所有子进程退出,主进程就会坐在那里等待子进程返回一些东西。所有子进程都已经退出,所以没有什么可以返回,导致永远等待

      【讨论】:

        【解决方案3】:

        尝试使用 os._exit(1) 代替 sys.exit();

        【讨论】:

          猜你喜欢
          • 2017-04-09
          • 1970-01-01
          • 2015-11-17
          • 2020-07-24
          • 2017-10-22
          • 1970-01-01
          • 2015-06-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多