UserWarning: MongoClient 在 fork 之前打开。仅在 fork 后创建 MongoClient

Posted

技术标签:

【中文标题】UserWarning: MongoClient 在 fork 之前打开。仅在 fork 后创建 MongoClient【英文标题】:UserWarning: MongoClient opened before fork. Create MongoClient only after forking 【发布时间】:2021-03-23 03:08:01 【问题描述】:

我在一个项目中使用mongoengine,我需要从multiprocessing 库中生成各种Process 对象。主进程使用数据库来确定需要做什么,然后生成一个新的Process 来处理它。每个Process 都需要访问数据库以获取自己的数据。我更喜欢使用Process 对象来保留

我已经对其进行了结构化,以便每个进程在启动时调用mongoengine.connect(name, host=host, port=port),但我仍然收到警告:

UserWarning: MongoClient opened before fork. Create MongoClient only after forking

警告意味着在生成新的Process 之前我无法打开 MongoClient。我还没有遇到任何不利影响,但我宁愿拥有一个强大的应用程序。

我想要一种模式,我可以将其应用于类似的问题:

import mongoengine
from multiprocessing import Process

mongoengine.connect(dbname, host=host, port=port)

def worker_process()
  mongoengine.connect(dbname, host=host, port=port)
  # Fetch lots of web data via bs4
  # do some work with the DB
  mongoengine.disconnect()

# do some work with the DB

process = Process(worker_process)
process.start()

# do some work with the DB

process.join()

这大大简化了我正在做的事情(检查它何时应该产生许多进程的无休止循环)

我读过关于在连接参数中添加connect=False,但据我所知,它只会使套接字连接变得懒惰,如果我在创建新的Process 之前开始使用数据库,它将仍然有同样的问题。

我还考虑过在每个 Process 中创建一个唯一别名(我可以只使用 PID 作为别名),但我似乎找不到告诉该进程使用该别名的方法。

我有两个不得已的办法:

    移动到线程并失去杀死线程的能力。此外,我对 Threading 的问题也不太熟悉。流程对我的目的一直很有用,并且让我印象深刻得多。我知道它们更重,但我不关心整体性能,更健壮。也许有人可以用“如果你只是......你不必担心线程”来说服我

    创建一个专用的Process 来使用数据库并确定要做什么,它会将任务报告回主进程以生成新的Process 对象。因此主进程永远不会有mongoengine 实例。如果没有必要,我真的不想走这条路,因为这将是一次重大的重组。

【问题讨论】:

【参考方案1】:

永不失败。做一大堆研究,一无所获。提出问题,接下来您就会知道答案就在您手中。

原来我的 docker 容器有问题,但我的桌面没有。我使用 MacOS 进行开发,在多处理库中偶然发现了这个脚注:

在 3.8 版中更改:在 macOS 上,spawn start 方法现在是 默认。分叉启动方法应该被认为是不安全的,因为它可以 导致子进程崩溃。请参阅 bpo-33725。

所以我在 3.8 上测试/验证并使用 spawn 方法,我什至没有意识到这一点。我刚刚添加了一行强制spawn 在启动时:

import multiprocessing as mp

# bla bla bla

if __name__ == '__main__':
    mp.set_start_method('spawn')

一切都开始工作了。

故事的寓意,如果有人想将 MongoEngine/pyMongo 与多处理库一起使用,请确保将启动方法设置为 spawn。在创建流程时会花费一些性能,但在这种情况下会创建更强大的分离。

【讨论】:

以上是关于UserWarning: MongoClient 在 fork 之前打开。仅在 fork 后创建 MongoClient的主要内容,如果未能解决你的问题,请参考以下文章

kde plot : UserWarning: Dataset has 0 variance;跳跃密度估计

matplotlib显示中文(解决UserWarning: findfont: Font family)

如何在屏蔽数据后避免由 python 使用 UserWarning 完成的隐式修复

UserWarning: Label not :NUMBER: is present in all training examples

Python 运行时出现 UserWarning: semaphore_tracker 问题解决(实际上是忽略方法)

如何在python 2.7中使用pymongo进行多处理池