繁体   English   中英

Windows中的Python多处理池奇怪行为

[英]Python multiprocessing Pool strange behavior in Windows

Python多处理池在Linux和Windows之间具有不同的行为。

当按工作进程数运行方法映射时,在Linux中,该进程在您作为参数指定的特定函数的范围内运行,但是在Windows中,每个工作进程均在父进程的范围内运行,并再次使用不应作为父进程的代码。 。

例如:(烧瓶仅用于使其类似于我的代码)

from multiprocessing import Pool, Event
from flask import Flask

print(">>> This code running for every each worker")

app = Flask(__name__)

terminating = None


def f(**kwargs):
    print("f()")
    x = kwargs.pop("x", 1)
    print(x * x)
    return x * x


def worker_warpper(arg):
    func, kwargs = arg
    return func(**kwargs)


def initializer(terminating_):
    global terminating
    terminating = terminating_


@app.route('/check', methods=['GET'])
def check():
    with Pool(processes=3) as pool:
        ls = [(f, {"x": 2}), (f, {"x": 5}), (f, {"x": 6})]
        pool_map = pool.map(worker_warpper, ls)
    return "Finished"


if __name__ == "__main__":
    print("Listening...")
    app.run(port=5151, host='0.0.0.0')

此代码块应在3个不同的进程上并行运行函数“ f”(仅函数“ f”)3次。

但是它将再次在顶部运行打印。 (这并不完全是针对每个流程的,但是运行“ f”的次数与要再次运行的顶部打印次数之间存在相关性)

print(">>> This code running for every each worker")

仅在Windows中,在Linux中只有“ f”再次运行。

输出:(Linux)

>>> This code running for new worker (not all of the workers)
Listening
...
 * Running on http://0.0.0.0:5151/ (Press CTRL+C to quit)
f()
4
f()
25
f()
36
127.0.0.1 - - 

[29/Jan/2017 11:46:26] "GET /check HTTP/1.1" 200 -

输出:(Windows)

>>> This code running for new worker (not all of the workers)
Listening
...
 * Running on http://0.0.0.0:5151/ (Press CTRL+C to quit)
>>> This code running for new worker (not all of the workers)
f()
4
f()
25
f()
36
127.0.0.1 - - 

[29/Jan/2017 11:46:26] "GET /check HTTP/1.1" 200 -

为什么Linux和Windows之间会有不同的行为? 那我该怎么办?

如果不清楚,请告诉我,我将尝试其他方式。

谢谢!

Windows和Linux之间的区别在于子进程的启动方式。 在Linux上,子进程是使用fork()启动的:新进程以与父进程相同的状态启动:python代码已被解释,并获得了父进程的内存副本。

在Windows上是完全不同的: spawn进程:启动新的python解释器,该解释器再次解析并执行python文件。 因此,顶部的print过程将再次执行。

有关详细信息,请参阅有关fork vs. spawn的文档

一个常见的陷阱是避免底部使用if __name__ == '__main__' 但是,由于您的代码中已经包含此代码,因此您非常接近“安全代码”。

我该怎么办?

您可以使用Threading代替多处理。 启动新线程时,新线程使用与父线程相同的内存空间。 缺点是,由于python的“全局解释器锁”,您只能使用一个CPU内核。

有关详细信息,请参见此讨论

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM