【问题标题】:testing python multiprocessing pool code with nose用鼻子测试python多处理池代码
【发布时间】:2013-09-09 12:35:11
【问题描述】:

我正在尝试使用 nose 编写测试以设置某些内容 使用多处理计算。

我有这个目录结构:

code/
    tests/
        tests.py

tests.py 看起来像这样:

import multiprocessing as mp


def f(i):
    return i ** 2


pool = mp.Pool()
out = pool.map(f, range(10))


def test_pool():
    """Really simple test that relies on the output of pool.map.
    The actual tests are much more complicated, but this is all
    that is needed to produce the problem."""
    ref_out = map(f, range(10))
    assert out == ref_out

if __name__ == '__main__':
    test_pool()

code 目录运行,python tests/tests.py 通过

nosetests tests/tests.py 未能完成。它启动了,但从来没有通过对pool.map的调用而只是挂起。

为什么会这样?最简单的解决方案是什么?

【问题讨论】:

  • nose 在运行测试时可能正在使用一些线程和/或日志记录。当与 UNIX 系统上的多处理混合时,这可能导致死锁。这不是 python 实现的问题,而是 fork() 函数本身的问题,它只分叉当前线程,请参阅this 答案以获得更详细的解释。
  • 我相信唯一的(?)解决方案是模拟 multiprocessing 模块。实际上,我看不到您的示例正在测试什么。它实际上是 multiprocessing.Pool.map 方法的单元测试,而不是 f 函数的单元测试!
  • 这是重现我的错误的最小示例。我正在测试大量使用 pool.map 的结果作为输入的其他东西。
  • 在多个核心上计算 map 是否重要?如果不是,则将pool.map 替换为普通的map
  • 显然可以解决它!但是,这不是一个选项:将pool.map 的使用视为问题的约束。

标签: python testing multiprocessing python-nose


【解决方案1】:

问题与pool.map 在“全局级别”被调用有关。通常你想避免这种情况,因为即使你的文件只是被导入,这些语句也会被执行。

鼻子必须import your module 才能找到您的测试并稍后执行它们,因此我相信问题发生在导入机制启动时(我没有花时间试图找出这种行为的确切原因)

您应该将初始化代码移至测试夹具; Nose 支持带有 with_setup 装饰器的固定装置。这是一种可能性(可能是保持poolout 为全局变量的最简单更改):

import multiprocessing as mp
from nose import with_setup

pool = None
out  = None

def f(i):
    return i ** 2

def setup_func():
    global pool
    global out
    pool = mp.Pool()
    out  = pool.map(f, range(10))

@with_setup(setup_func)
def test_pool():
    """Really simple test that relies on the output of pool.map.
    The actual tests are much more complicated, but this is all
    that is needed to produce the problem."""
    global out
    ref_out = map(f, range(10))
    assert out == ref_out

if __name__ == '__main__':
    test_pool()

执行:

$ nosetests tests/tests.py
.
----------------------------------------------------------------------
Ran 1 test in 0.011s

OK

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多