尽管将 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多进程与mongo

PYTHON 为啥我的 python IDLE 不能将 numpy 识别为模块,尽管在 cmd 中运行 pythob 时可以正常使用 numpy?

python:多进程,多进程队列,多进程管道,Manager,进程锁,进程池

尽管将 Python multiprocessing.Lock 作为目标函数参数传递,但在并行化时为无

Gevent简明教程

尽管 Python Pandas 中有共享值,但不能将 df2 合并到 df1 吗? [关闭]