[英]Python Why must multiprocessing.set_start_method be invoked in the __name__ == '__main__' clause?
[英]Does pytest support multiprocessing.set_start_method?
multiprocessing.set_start_method
的文档指出:
请注意,这应该最多被调用一次,并且应该在主模块的 if name == ' main ' 子句中受到保护。
但是,如果我将multiprocessing.set_start_method('spawn')
放在 pytest 模块夹具中,我不知道它是否会完美运行。
确实,如文档中所述,如果尝试从多个单元测试函数调用multiprocessing.set_start_method()
,将会遇到麻烦。 此外,这将影响您的整个程序,并且可能会与整个测试套件严重地互操作。
另外,您可以使用
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
如果您确实总是想使用相同的启动方法,则可以在源代码树根目录下的conftest.py
文件中的会话范围内设置它。 例如
# conftest.py
import multiprocessing
import pytest
@pytest.fixture(scope="session", autouse=True)
def always_spawn():
multiprocessing.set_start_method("spawn")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.