如果导入PySide,python子进程在numpy点上崩溃

oto*_*nan 9 python numpy multiprocessing pyside

当使用带有numpy和PySide导入的pytnon多处理池时,我的机器上发生了这种非常特殊的悬挂.这是我迄今为止在生活中看到的最纠结的错误:)以下代码:

import numpy as np
import PySide


def hang():
    import multiprocessing
    pool = multiprocessing.Pool(processes = 1)
    pool.map(f, [None])


def f(ignore):
    print('before dot..')
    np.dot(np.zeros((128, 1)), np.zeros((1, 32)))
    print('after dot.')


if __name__ == "__main__":
    hang()
    print('success!')
Run Code Online (Sandbox Code Playgroud)

仅在'点之前'挂起打印.但它应该打印

before dot..
after dot.
success!
Run Code Online (Sandbox Code Playgroud)

我不是gdb专家,但看起来像gdb显示进程在'np.dot'行退出(或崩溃):

[Inferior 1 (process 2884) exited normally]
Run Code Online (Sandbox Code Playgroud)

我可以采取一些神奇的修改来防止悬挂:

  • 如果你减少进入'点'的数组的形状(例如从128到127)
  • (!)如果你将进入'dot'的数组的形状从128增加到256
  • 如果你不使用多处理并只运行函数'f'
  • (!!!)如果你注释掉在代码中没有使用的PySide导入

任何帮助表示赞赏!

包装版本:

numpy = 1.8.1或1.7.1 PySide = 1.2.1或1.2.2

Python版本:

在达尔文上的Python 2.7.5(默认,2013年9月12日,21:33:34)[GCC 4.2.1兼容的Apple LLVM 5.0(clang-500.0.68)]

要么

在达尔文上的Python 2.7.6(默认,2014年4月9日,11:48:52)[GCC 4.2.1兼容的Apple LLVM 5.1(clang-503.0.38)]

注意:在寻找信息时,我简化了原始代码并提出了一些问题.但是这里有一堆更新,以便为可能遇到此错误的其他人保留历史记录(例如,我开始使用matplotlib,而不是使用pyside)

更新:我缩小了pylab import以导入带有pyside后端的matplotlib并更新了要运行的代码.

更新:我正在修改帖子只导入PySide而不是:

import matplotlib
matplotlib.use('qt4agg')
matplotlib.rcParams['backend.qt4']='PySide'
import matplotlib.pyplot
Run Code Online (Sandbox Code Playgroud)

更新:初始统计信息显示它是仅限Mac的问题.有3人在Ubuntu上工作,有2人在Mac上工作.

更新:点操作之前的print(os.getpid())给了我pid,我没有在'top'中看到它显然意味着它崩溃并且多处理等待死进程.出于这个原因,我无法附加调试器.我相应地编辑了主要问题.

jta*_*lor 7

这是numpy使用的一些BLAS库的一般问题dot.

已知使用GNU Openmp构建的Apple Accelerate和OpenBlas在fork的两侧都不安全(父进程和子进程多处理创建).他们将陷入僵局.

这不能通过numpy修复,但有三种解决方法:

  • 使用基于pthreads的netlib BLAS,ATLAS或git master OpenBlas(2.8.0不起作用)
  • 使用python 3.4及其新的多处理spawnforkserver启动方法
  • 使用线程而不是多处理,numpy为大多数昂贵的操作发布了gil,因此您可以在典型的桌面计算机上存档正常的线程加速


小智 0

我认为这是多处理模块的问题。

尝试使用以下内容代替。

import numpy as np
import PySide


    def hang():
        import multiprocessing.dummy as multiprocessing
        pool = multiprocessing.Pool(processes = 1)
        pool.map(f, [None])


    def f(ignore):
        print('before dot..')
        np.dot(np.zeros((128, 1)), np.zeros((1, 32)))
        print('after dot.')


    if __name__ == "__main__":
        hang()
        print('success!')
Run Code Online (Sandbox Code Playgroud)