在Python 2.7中,有一种方法可以识别当前的forked / spawned进程是否是子进程实例(而不是作为常规进程启动)。我的目标是如果它是一个子进程,则设置一个不同的全局变量(例如,为其他具有大于0的数字的其他池创建一个大小为0的池)。
我无法将参数传递给函数(被调用以在子进程中执行),因为即使在调用函数之前,该进程也已经初始化,因此也是全局变量(特别是对于生成的进程)。 / p>
此外,由于我的应用程序在Web服务容器(flask)中运行,因此我无法使用freeze_support(当然,除非我很想知道如何使用它)。因此,没有主要方法。
非常感谢任何帮助。
如果在Windows上运行它,将进入无限循环的示例代码:
from multiprocessing import Pool, freeze_support
p = Pool(5) # This should be created only in parent process and not the child process
def f(x):
return x*x
if __name__ == '__main__':
freeze_support()
print(p.map(f, [1, 2, 3]))
答案 0 :(得分:2)
我建议将程序重构为更像下面的示例代码。您提到您没有main
函数,但您可以创建一个处理池的包装器:
from multiprocessing import Pool, freeze_support
def f(x):
return x*x
def handle_request():
p = Pool(5) # pool will only be in the parent process
print(p.map(f, [1, 2, 3]))
p.close() # remember to clean up the resources you use
p.join()
return
if __name__ == '__main__':
freeze_support() # do you really need this?
# start your web service here and make it use `handle_request` as the callback
# when a request needs to be serviced
听起来你有点XY problem。您不应该在全球范围内创建流程池。这很糟糕。你给你的子进程访问他们自己的进程对象,这允许你不小心做坏事,比如让子进程加入自己。如果在为每个请求调用的包装器中创建池,则无需担心全局变量。
在评论中,您提到过您需要一个持久池。在每个请求上创建池确实有一些开销,但它比拥有全局池更安全。此外,您现在可以同时处理多个请求,假设您的Web服务处理其自己的线程/进程中的每个请求,而没有多个请求通过尝试使用相同的池来相互欺骗。我强烈建议您尝试使用此方法,如果它不符合您的性能规范,您可以考虑以其他方式(即没有全局池)优化它以满足您的规范。
另一个注意事项:如果您打算将脚本捆绑到Windows可执行文件中,则只需要调用multiprocessing.freeze_support()。如果你不这样做,请不要使用它。
答案 1 :(得分:0)
将池创建移动到主要部分,只创建一个多处理池,只在主进程中创建一个:
from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
p = Pool(5)
print(p.map(f, [1, 2, 3]))
这是有效的,因为在__main__
名称中执行的唯一进程是原始进程。生成的进程使用__mp_main__
模块名称运行。
为孩子
创建一个大小为0的游泳池
子进程永远不应该启动新的多处理池。仅从单个入口点处理您的流程。