尽管将 Python multiprocessing.Lock 作为目标函数参数传递,但在并行化时为无
Posted
技术标签:
【中文标题】尽管将 Python multiprocessing.Lock 作为目标函数参数传递,但在并行化时为无【英文标题】:Python multiprocessing.Lock is Noned upon parallelizing despite passing it as target function argument 【发布时间】:2021-12-22 12:42:40 【问题描述】:将multiprocessing.Lock
(或RLock
)传递给multiprocessing.context.Process
失败,锁值为None
我在几个小时内尝试了很多东西。没有任何效果。
起初我在使用 ForkingPickler 时遇到了挑选错误。然后我看到了一些其他的 SO 答案,据说锁需要作为目标函数的参数传递。我这样做了。例如,我尝试将锁作为参数传递,如下所示:https://pymotw.com/2/multiprocessing/communication.html#controlling-access-to-resources
然而,一旦我进入目标worker_function,锁似乎被替换为None。函数的 lock 参数神奇地被 None 替换。
请看下面我的尝试。
目标函数
参见论点 2,shared_lock: Lock
:
from multiprocessing import Queue, Lock
from neuraxle.base import ExecutionContext
# ...
def worker_function(queue_worker: QueueWorker, shared_lock: Lock, context: ExecutionContext, use_savers: bool, additional_worker_arguments):
try:
context.flow._lock = shared_lock
# some more code after...
将锁分派给工人的主要功能:
这里,我也有类似的,见shared_lock
变量:
from multiprocessing import Lock, RLock
from multiprocessing.context import Process
from threading import Thread
use_processes = True # could be false as well.
# some more code before...
thread_safe_context = context.make_thread_safe()
shared_lock: Lock = context.flow._lock # trying to save the lock or rlock
context.flow._lock = None
parallel_call = Thread
if use_processes:
parallel_call = Process
p = parallel_call(
target=worker_function,
args=(thread_safe_self, shared_lock, thread_safe_context, self.use_savers, worker_arguments)
)
# some more code after...
在简单地用context.flow._lock = None
说明上述要点之前,我已经对代码进行了几次其他重构以达到这一点。我开始变得非常烦躁。我想最终找到解决方案。
请注意,在自定义 QueueWorker 类中传递队列是有效的。
提示:我发现 Manager 类或类似的东西可能会有所帮助,但我不知道如何在这里使用它,并且我尝试按照文档中的指示传递锁(如上链接)。感谢您的帮助!
【问题讨论】:
你做了很多你真的不应该做的奇怪的事情,弄乱了未记录的实现细节,直接访问multiprocessing.context.Process
(无论如何这几乎总是错误的Process
实现),而不是使用if __name__ == '__main__'
守卫等
您能否指出良好的流程实施来获得建设性的评论?对于 if 名称,我的代码粘贴在此处,通常位于某些类的函数内部。在这里复制完整的课程太长了,所以我过于简化了。
multiprocessing.Process
,或者如果您正在使用多处理上下文(使用multiprocessing.get_context
创建),则在上下文对象上使用ctx.Process
。
【参考方案1】:
它只与我如何创建作为参数传递的锁有关。
做:
from multiprocessing import Lock, Manager
lock = Manager().Lock()
不要这样做:
from multiprocessing import Lock, Manager
lock = Lock()
编辑:正如@user2357112 所述,应该使用multiprocessing.Process
而不是multiprocessing.context.Process
,或者应该首先使用multiprocessing.get_context()
。这似乎是错误的一部分。
【讨论】:
将multiprocessing.Lock
实例作为参数传递给工作进程是非常好的。您的其余代码存在错误,而管理器锁定实现恰好与这些错误更好地交互。
能否具体说明为什么 context.Process 中会出现错误?
不是context.Process
中的错误。 你的代码中的错误。使用multiprocessing.context.Process
是其中一个错误——它可能被命名为Process
,但这并不意味着它是您应该使用的流程实现。以上是关于尽管将 Python multiprocessing.Lock 作为目标函数参数传递,但在并行化时为无的主要内容,如果未能解决你的问题,请参考以下文章
PYTHON 为啥我的 python IDLE 不能将 numpy 识别为模块,尽管在 cmd 中运行 pythob 时可以正常使用 numpy?
python:多进程,多进程队列,多进程管道,Manager,进程锁,进程池