pytest是否支持multiprocessing.set_start_method?

时间:2018-10-22 01:21:03

标签: python pytest python-multiprocessing

multiprocessing.set_start_method的文档请注意:

  

请注意,该调用最多应调用一次,并且应在主模块的if name ==' main '子句中进行保护。

但是,如果我将multiprocessing.set_start_method('spawn')放在pytest模块固定装置中,我不知道它会完美地工作。

1 个答案:

答案 0 :(得分:0)

确实,如文档中所述,如果尝试从多个单元测试函数中调用multiprocessing.set_start_method(),则会遇到麻烦。而且,这会影响您的整个程序,并且可能会与整个测试套件严重地互操作。

但是,也存在一种in the documentation描述的解决方法:

  

或者,您可以使用get_context()获取上下文   宾语。上下文对象具有与多处理相同的API   模块,并允许一个人在同一时间使用多种启动方法   程序。

     
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join() ```

此方法可用于每次测试,以避免讨论兼容性问题。它可以与“ monkeypatching”或“ mocking”结合使用不同的启动方法来测试您的类:

# my_class.py

import multiprocessing

class MyClass:

    def __init__(self):
        self._queue = multiprocessing.Queue()

    def process(self, x):
        # Very simplified example of a method using a multiprocessing Queue 
        self._queue.put(x)
        return self._queue.get()
# tests/test_my_class.py

import multiprocessing
import my_class

def test_spawn(monkeypatch):
    ctx = multiprocessing.get_context('spawn')
    monkeypatch.setattr(my_class.multiprocessing, "Queue", ctx.Queue)
    obj = my_class.MyClass()
    assert obj.process(6) == 6

def test_fork(monkeypatch):
    ctx = multiprocessing.get_context('fork')
    monkeypatch.setattr(my_class.multiprocessing, "Queue", ctx.Queue)
    obj = my_class.MyClass()
    assert obj.process(6) == 6