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

Python多处理池在Windows中的奇怪行为,python,python-3.x,multiprocessing,Python,Python 3.x,Multiprocessing,Python多处理池在Linux和Windows之间具有不同的行为 在Linux中,当按工作者数量运行方法映射时,它会在您作为参数指定的特定函数的范围内运行进程, 但在Windows中,每个工作进程都在父进程的范围内运行,并再次使用不应该使用的代码 例如:(烧瓶只是为了使它与我的代码相似) 这段代码应该在3个不同的进程中并行运行函数“f”(仅函数“f”)3次 但它再次在顶部运行打印。(这并不完全适用于每个流程,但运行“f”的次数与顶部再次运行的打印次数之间存在关系) print(“>>>此代码为

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

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

例如:(烧瓶只是为了使它与我的代码相似)

这段代码应该在3个不同的进程中并行运行函数“f”(仅函数“f”)3次

但它再次在顶部运行打印。(这并不完全适用于每个流程,但运行“f”的次数与顶部再次运行的打印次数之间存在关系)

print(“>>>此代码为每个工作人员运行”)

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

输出:(Linux)

输出:(Windows)

为什么linux和windows之间有不同的行为? 我能做些什么呢

如果不清楚,请告诉我,我将以不同的方式尝试


谢谢

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

在Windows上则完全不同:进程是
spawn
ed:启动一个新的python解释器,它再次解析python文件并执行它。这就是再次执行顶部的
打印
过程的原因

有关详细信息,请参阅

一个常见的陷阱是避免底部的
if uuuu name_uuu=='\uuuu main_uuu'
。但既然你的代码中已经有了这个,你就非常接近“安全代码”

我能怎么办

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

详情请参阅

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')
>>> 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 -
>>> 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 -