首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何杀死多处理模块创建的僵尸进程?

如何杀死多处理模块创建的僵尸进程?
EN

Stack Overflow用户
提问于 2013-10-11 23:42:24
回答 2查看 26K关注 0票数 21

我对multiprocessing模块非常陌生。我刚刚尝试创建以下内容:我有一个进程,它的任务是从RabbitMQ获取消息并将其传递到内部队列(multiprocessing.Queue)。然后,我想要做的是:在新消息传入时生成一个进程。它可以工作,但在作业完成后,它会留下一个未被其父进程终止的僵尸进程。下面是我的代码:

主要进程:

代码语言:javascript
复制
 #!/usr/bin/env python

 import multiprocessing
 import logging
 import consumer
 import producer
 import worker
 import time
 import base

 conf = base.get_settings()
 logger = base.logger(identity='launcher')

 request_order_q = multiprocessing.Queue()
 result_order_q = multiprocessing.Queue()

 request_status_q = multiprocessing.Queue()
 result_status_q = multiprocessing.Queue()

 CONSUMER_KEYS = [{'queue':'product.order',
                   'routing_key':'product.order',
                   'internal_q':request_order_q}]
 #                 {'queue':'product.status',
 #                  'routing_key':'product.status',
 #                  'internal_q':request_status_q}]

 def main():
     # Launch consumers
     for key in CONSUMER_KEYS:
         cons = consumer.RabbitConsumer(rabbit_q=key['queue'],
                                        routing_key=key['routing_key'],
                                        internal_q=key['internal_q'])
         cons.start()

     # Check reques_order_q if not empty spaw a process and process message
     while True:
         time.sleep(0.5)
         if not request_order_q.empty():
             handler = worker.Worker(request_order_q.get())
             logger.info('Launching Worker')
             handler.start()

 if __name__ == "__main__":
     main()

这是我的工人:

代码语言:javascript
复制
 import multiprocessing
 import sys 
 import time
 import base

 conf = base.get_settings()
 logger = base.logger(identity='worker')

 class Worker(multiprocessing.Process):

     def __init__(self, msg):
         super(Worker, self).__init__()
         self.msg = msg 
         self.daemon = True

     def run(self):
         logger.info('%s' % self.msg)
         time.sleep(10)
         sys.exit(1)

因此,在处理完所有消息之后,我可以使用ps aux命令查看进程。但我真的希望他们一旦完成就被终止。谢谢。

EN

回答 2

Stack Overflow用户

发布于 2016-02-13 05:15:27

使用multiprocessing.active_children比使用Process.join更好。函数active_children将清除自上次调用active_children以来创建的所有僵尸。方法join等待选定的进程。在此期间,其他进程可能会终止并成为僵尸,但父进程不会注意到,直到加入等待的方法。要查看实际操作,请执行以下操作:

代码语言:javascript
复制
import multiprocessing as mp
import time


def main():
    n = 3
    c = list()
    for i in range(n):
        d = dict(i=i)
        p = mp.Process(target=count, kwargs=d)
        p.start()
        c.append(p)
    for p in reversed(c):
        p.join()
        print('joined')


def count(i):
    print(f'{i} going to sleep')
    time.sleep(i * 10)
    print(f'{i} woke up')


if __name__ == '__main__':
    main()

上面将创建3个进程,每个进程相隔10秒终止。正如代码所示,最后一个进程首先加入,所以之前终止的另外两个进程将在20秒内成为僵尸进程。您可以使用以下命令查看它们:

代码语言:javascript
复制
ps aux | grep Z

如果进程按照它们将终止的顺序等待,就不会有僵尸。删除对函数reversed的调用以查看此案例。然而,在实际的应用程序中,我们很少知道子代将终止的顺序,因此使用multiprocessing.Process.join方法将导致一些僵尸。

替代的active_children不会留下任何僵尸。在上面的示例中,将循环for p in reversed(c):替换为:

代码语言:javascript
复制
while True:
    time.sleep(1)
    if not mp.active_children():
        break

看看会发生什么。

票数 11
EN

Stack Overflow用户

发布于 2015-04-16 07:15:05

使用active_children。multiprocessing.active_children

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19322129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档