首页 > 解决方案 > Python - 如何使用 MongoDB (pymongo) 和 multiproccesing 而无需“在 fork 之前打开 MongoClient”。问题?

问题描述

我正在使用多处理,但我收到此错误“MongoClient 在 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()

标签: pythonmongodbmultithreadingpymongo

解决方案


让每个进程打开自己的 MongoDB 连接。

注意中的警告get_mongo_client();如果你想要从任何地方安全调用的东西,你需要_mongo_client用当前进程的 PID “标记”,如果对象的 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()

推荐阅读