【问题标题】:Python - How to make use of MongoDB (pymongo) & multiproccesing without the "MongoClient opened before fork." issue?Python - 如何在没有“MongoClient 在 fork 之前打开”的情况下使用 MongoDB (pymongo) 和 multiproccesing。问题?
【发布时间】:2020-04-27 20:32:31
【问题描述】:
我正在使用多处理,但我收到此错误“MongoClient opens before fork”。对于每个过程。我做了一些研究并得出结论,我现在正在创建多个 MongoClients(每个子进程一个)。但我没有找到真正的解决方案。每个进程都在使用 MongoDB 连接(我使用 pymongo 作为连接器)。有人可以帮我吗?
代码:
def func1():
while True:
col1.insert_one({...})
...
def func2():
while True:
col2.insert_one({...})
...
if __name__ == "__main__":
# MongoDB
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["testdb"]
col1 = mydb["col1"]
col2 = mydb["col2"]
# Multiproccesing
p1 = Process(target=func1)
p2 = Process(target=func2)
p1.start()
p2.start()
p1.join()
p2.join()
【问题讨论】:
标签:
python
mongodb
multithreading
pymongo
【解决方案1】:
让每个进程打开自己的 MongoDB 连接。
注意get_mongo_client()中的警告;如果您想要从任何地方安全调用的东西,您需要使用当前进程的 PID “标记”_mongo_client,如果对象的 PID 错误,则丢弃该对象。
_mongo_client = None # Global per process
def get_mongo_client():
# Make sure not to call this within the master process, or things
# will break again.
global _mongo_client
if _mongo_client is None:
_mongo_client = pymongo.MongoClient("mongodb://localhost:27017/")
return _mongo_client
def get_mongo_col(collection, database="testdb"):
client = get_mongo_client()
return client[database][collection]
def func1():
col1 = get_mongo_col("col1")
while True:
col1.insert_one({})
# ...
def func2():
col2 = get_mongo_col("col2")
while True:
col2.insert_one({})
# ...
def main():
# Multiproccesing
p1 = Process(target=func1)
p2 = Process(target=func2)
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == "__main__":
main()