【问题标题】:Python concurrency with imported modules导入模块的 Python 并发
【发布时间】:2018-10-31 22:07:10
【问题描述】:

为什么导入本地模块会导致 Concurrent.futures.ProcessPoolExecutor 抛出 BrokenProcessPool 异常?

当我导入本地模块时,我在运行文件时收到了 BrokenProcessPool 异常。我已经尝试注释掉该模块中的所有内容,并且得到了相同的结果。我还尝试了其他具有相同结果的文件/模块。但是,如果我注释掉 import 语句,或者将它放在 main() 函数中,它不会终止进程并引发异常。我用其他本地模块尝试过同样的事情,我得到了同样的结果。为什么会发生这种情况,我该怎么做才能避免异常?

我正在尝试将 concurrent.futures 与 ProcessPoolExecutor 一起使用。我的代码示例基于这个问题的最佳答案:Parallelize apply after pandas groupby

这是我的版本:

import pandas as pd
import numpy as np
import time
from concurrent.futures import ProcessPoolExecutor, as_completed
import analysis_helper # a local module

print(__name__)
nrows = 15000
np.random.seed(1980)
df = pd.DataFrame({'a': np.random.permutation(np.arange(nrows))})

def f1(group):
    time.sleep(0.0001)
    return group

def main():
    with ProcessPoolExecutor(12) as ppe:
        futures = []
        results = []

        for name, group in df.groupby('a'):
            p = ppe.submit(f1, group)
            futures.append(p)

        for future in as_completed(futures):
            r = future.result()
            results.append(r)

        df_output = pd.concat(results)
        print(df_output)

if __name__ == '__main__':
    main()

删除了 analysis_helper 的结果:

runfile('C:/dev/.../test_parallelizer_pandas.py', wdir='C:/dev/...')
__main__
           a
1255    1733
3372   11015
5318    4571
7076   14510
10545  10749
3340     483
11844   3736
3681   14509
2222    1041
3640   11014
4288    7852
12257   1040
2101   11034
14938   3065
8449    1842
7231   10746
7509    4353
4898    3797
2941     866
7497   14520
8302   11013
13882   9924
12007   1042
1567   10747
13135   7856
7742     485
13709  12571
1946   11012
5634    7848
7044    4354
     ...
3441   14213
179    14361
6723   12134
7528    5905
9273   12420
9916    3614
134    10166
11654   5854
11848  12133
14055   4278
6100   14360
726    14981
13139  14982
12552  14983
5393   14984
6927   14986
8108   14985
12665  14987
8587   14988
11437  14989
4191   14990
6877   14991
4997   14994
13527  14995
9477   14993
2930   14996
5456   14992
781    14997
3287   14998
13386  14999

[15000 rows x 1 columns]

使用 analysis_helper 的结果:

runfile('C:/dev/.../test_parallelizer_pandas.py', wdir='C:/dev/...')
__main__
Traceback (most recent call last):

  File "<ipython-input-7-7d6a88ec5a87>", line 1, in <module>
    runfile('C:/dev/.../test_parallelizer_pandas.py', wdir='C:/dev/...')

  File "C:\Users\david\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
    execfile(filename, namespace)

  File "C:\Users\david\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/dev/.../test_parallelizer_pandas.py", line 42, in <module>
    main()

  File "C:/dev/.../test_parallelizer_pandas.py", line 35, in main
    r = future.result()

  File "C:\Users\david\Anaconda3\lib\concurrent\futures\_base.py", line 425, in result
    return self.__get_result()

  File "C:\Users\david\Anaconda3\lib\concurrent\futures\_base.py", line 384, in __get_result
    raise self._exception

BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.

注意:这只发生在 ProcessPoolExecutor 上,而不是 ThreadPoolExecutor。

【问题讨论】:

    标签: python concurrency main concurrent.futures


    【解决方案1】:

    如果您使用的是 macOS,定义以下环境变量之一可以作为临时解决方法。

    OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES  
    

    阅读有关该问题的更多信息here

    NO_PROXY='*'
    

    阅读更多关于该问题的信息here

    第二个选项在 macOS 10.14.1 和 Python 3.6.0 上对我有用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多