Python 多处理和金字塔:如何确保子进程实际结束?

Python 多处理和金字塔:如何确保子进程实际结束?,python,queue,multiprocessing,pyramid,waitress,Python,Queue,Multiprocessing,Pyramid,Waitress,我试图在我的金字塔应用程序中有一个工作进程池,可以用来执行CPU密集型(或长时间运行的)后台任务,我不想让视图陷入困境。我现在所做的一切都是有效的,但有一个问题:如果女服务员退出了终止服务(就像重新加载一样),工人们就会继续逗留,我不知道如何向他们发出停止的信号 编辑:使用Gunicorn(或仅从某个文件运行)时,这似乎不是问题。这可能是女服务员的问题吗 编辑2:好的。或者Gunicorn只是以不同的方式处理,让它看起来更好 将多处理导入为mp 从队列导入空作为QueueEmptyError 类

我试图在我的金字塔应用程序中有一个工作进程池,可以用来执行CPU密集型(或长时间运行的)后台任务,我不想让视图陷入困境。我现在所做的一切都是有效的,但有一个问题:如果女服务员退出了终止服务(就像重新加载一样),工人们就会继续逗留,我不知道如何向他们发出停止的信号

编辑:使用Gunicorn(或仅从某个文件运行)时,这似乎不是问题。这可能是女服务员的问题吗

编辑2:好的。或者Gunicorn只是以不同的方式处理,让它看起来更好

将多处理导入为mp
从队列导入空作为QueueEmptyError
类MyPool(对象):
def u u init u u;(self,进程=10,队列=None):
self.jobqueue=如果队列不是None-else,则为队列mp.queue()
self.procs=[]
self.running=True
对于范围内的i(过程):
worker=mp.Process(target=self.\u worker,daemon=True)
self.procs.append(worker)
worker.start()
定义(自我):
self.stopall()
def stopall(自身):
self.running=False
对于self.procs中的工作人员:
worker.join()
def_工作人员(自身):
自运行时:
尝试:
self.\u dojob(self.jobqueue.get(True,1))
除QueueEmptyError外:
通过
def_dojob(self,taskdata):
打印(str(taskdata)+“正在发生”)
类PoolMaster(对象):
定义初始化(自):
self.pools=[]
self.aqueue=mp.Queue()
self.apool=MyPool(6,self.aqueue)
self.pools.append(self.apool)
定义(自我):
对于self.pools中的池:
pool.stopall()
def do_某事(自我):
self.aqueue.put_nowait(‘某物’)
PoolMaster在我的项目的main()函数中实例化一次,并通过将其添加到所有事件中向所有视图公开


我以前尝试过的是在
\uu del\uuu
发生时向队列中添加一个“毒药丸”,但事实证明
\uu del\uu
似乎根本没有被调用。我不想使用multiprocessing自己的池,因为它们似乎是为了一次运行一组工作负载而设计的,而不是一直在队列上工作。那么,在实际应用程序退出后,如何阻止它们运行呢?

您可以为
MyPool
中的每个工作人员使用
管道(例如,
取消管道
)。然后,您的员工会定期收听
管道
,查找一些取消代码(例如,
True
)。要在辅助进程中使用管道,请执行以下操作:

connections = mp.Pipe()
self.cancelPipes.append(connections[0])
worker = mp.Process(target=self._worker, daemon=True, args=[connections[1]])

然后,如果要取消所有人,请执行以下操作:

for c in self.cancelPipes:
    c.send(True)
工人们会检查他们是否应该停止这样做:

gotSomething = cancelPipe.poll()
if gotSomething:
    cancel = cancelPipe.recv()
    if cancel:
        # Stop your worker

好的,我找到了一种方法,通过更改
\u worker
函数来实现:

def _worker(self):
    while True:
        try:
            self._dojob(self.jobqueue.get(True, 3))
        except QueueEmptyError:
            pass
        if os.getppid() == 1:
            print('Parent process died, stopping worker.')
            sys.exit(0)
当父进程在没有结束守护进程的情况下死亡时,工作进程将返回1,而不是类UNIX系统上的父进程ID。每隔3秒钟,它就会停止等待队列中的新对象,并进行检查


但是我觉得这不是正确的方法。

“那么,当你想取消所有人时”-看,这实际上就是问题所在。当应用程序停止/终止时,如何执行类似的操作(或代码)?或者,更确切地说,当这种情况发生时,我如何确保线程不会粘在一起?我认为将daemon设置为True就可以了。