Python 多处理管理器在 flask 中使用时显示错误 API

Python multiprocessing manager showing error when used in flask API

我对做我想做的事情的最佳方式感到很困惑。

我想要什么?

  1. API 调用 flask 应用程序
  2. Flask 路由使用 Process 模块启动 4-5 个多进程,并使用共享的 Managers().list()
  3. 组合结果(在切片 pandas 数据帧上)
  4. Return计算结果返回给客户端。

我的实现:

pos_iter_list = get_chunking_iter_list(len(position_records), 10000)

manager = Manager()
data_dict = manager.list()
processes = []
for i in range(len(pos_iter_list) - 1):
    temp_list = data_dict[pos_iter_list[i]:pos_iter_list[i + 1]]
    p = Process(
        target=transpose_dataset,
        args=(temp_list, name_space, align_namespace, measure_master_id, df_searchable, products,
              channels, all_cols, potential_col, adoption_col, final_segment, col_map, product_segments,
              data_dict)
    )
    p.start()
    processes.append(p)
for p in processes:
    p.join()

我的目录结构:

- main.py(flask entry point)
- helper.py(contains function where above code is executed & calls transpose_dataset function)

我在 运行 时遇到同样的错误? 运行时错误:找不到提供的模块“mp_main”的根路径。发生这种情况是因为模块来自不提供文件名信息的导入挂钩,或者因为它是命名空间包。在这种情况下,需要明确提供根路径。

不确定这里发生了什么,当使用 if __name__ == '__main__':

从 sample.py 文件调用时,经理列表工作正常

更新:同一段代码在我的 MacBook 上运行良好,但在 windows os.

上运行良好

一个样品瓶API致电:

@app.route(PREFIX + "ping", methods=['GET'])
def ping():
    man = mp.Manager()
    data = man.list()
    processes = []
    for i in range(0,5):
        pr = mp.Process(target=test_func, args=(data, i))
        pr.start()
        processes.append(pr)

    for pr in processes:
        pr.join()

    return json.dumps(list(data))

Stack 有一个持续的错误阻止我发表评论,所以我只写一个答案..

Python 有 2 种(主要)方式来启动新进程:“spawn”和“fork”。 Fork 是仅在 *nix(阅读:linux 或 macos)中可用的系统命令,因此 spawn 是 windows 中唯一的选项。 3.8 之后,spawn 将成为 MacOS 上的默认设置,但 fork 仍然可用。最大的区别是 fork 基本上复制了现有进程,而 spawn 启动了一个全新的进程(就像打开一个新的 cmd window)。原因和方式有很多细微差别,但是为了能够 运行 您希望子进程使用 spawn 运行 的功能,子进程必须 import 主文件.导入文件等同于只执行该文件,然后通常将其命名空间绑定到一个变量:import flask 将 运行 flask/__ini__.py 文件,并将其全局命名空间绑定到变量 flask。然而,通常有代码仅供主进程使用,不需要在子进程中导入/执行。在某些情况下,再次 运行ning 该代码实际上会破坏某些东西,因此您需要防止它 运行ning 在主进程之外。考虑到这一点,因为“魔术”变量 __name__ 仅等于主文件中的 "__main__"(而不是在子进程中或导入模块时)。

在您的特定情况下,您正在创建一个新的 app = Flask(__name__),它会在您 运行 服务器之前进行一些验证和检查。当 运行 来自子进程时,它是这些 setup/validation 步骤之一。通过完全不让它 运行 来修复它是 imao 更干净的解决方案,但你也可以通过给它一个不会被绊倒的值来修复它,然后永远不要启动那个辅助服务器(再次通过保护它if __name__ == "__main__":)