Python死锁与打包和mayavi有关



我有一个奇怪的问题,希望有人能解释一下。

我有一段复杂的代码,最初是一个充满脚本的目录,我决定将其重新编写成一个包。这一代码更改似乎引发了一些奇怪的死锁。

以下是对该问题进行规范再现的尝试;它失败了,因为这个代码按预期运行。实际上,复制这个问题可能需要大量的代码;但我一辈子都无法想象上下文中令人反感的代码片段有什么不同。

import numpy as np
from scipy.sparse import csr_matrix
from threading import Thread
def dummy():
    print 'this is printed'
    I = np.eye(3)
    print 'all is still fine'
    csr_matrix(I)
    print 'this is never printed; csr_matrix appears to be a trigger for deadlock'
    print np.ones(4)
    print 'same problem; somehow, printing ndarrays is no longer cool either'
thr = Thread(target=dummy)
thr.start()

也许文档中的这个简短评论是相关的?我不确定我是否完全理解这里所说的

http://docs.python.org/2/library/threading#importing-在线程代码中

首先,除了在主模块中,导入不应该有生成新线程然后以任何方式等待该线程的副作用。如果派生的线程直接或间接尝试导入模块,则不遵守此限制可能会导致死锁

一些上下文:我使用的是python 2.7,numpy 1.8,我试图从mayavi/tratritsui线程中生成这个新线程(我不明白为什么它应该相关,在包结构之前它工作得很好,但还好)。此外,在我的派生线程中有大量的numpy/scipy代码,它们执行得非常好;它只是打印ndarrays和创建稀疏矩阵,到目前为止,这些矩阵已被证明是死锁的触发因素。

我怀疑与mayavi有一些奇怪的交互,因为关闭mayavi窗口会导致所有死锁的线程重新开始运行。也许这些特定的语句触发了python线程向mayavi线程让步,但它们不知何故未能再次获得焦点?

任何能进一步缩小这个谜团的暗示都将不胜感激!

从您的评论来看,您似乎在某个子模块的顶层启动了UI事件循环。这不是一个好主意,因为它会导致与文档中提到的完全相同的问题。import foo永远不应该启动UI事件循环。问题是主线程获取导入锁来处理模块的导入。此模块在完成导入之前启动UI事件循环。这与等待其他线程完成的情况基本相同;您正在等待UI循环结束。如果您的UI启动了其他线程,则在其他线程中运行的代码将无法导入任何内容(csr_matrix()ndarray.__repr__()都导入其他模块),因为主线程仍持有导入锁。

相关内容

  • 没有找到相关文章

最新更新