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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (120)

我试图创建以下内容:从RabbitMQ获取消息并将其传递给内部队列(multiprocessing.Queue)。然后,我想要做的是:在新消息进来时产生一个进程。它可以工作,但是在作业完成后,它会留下一个僵尸进程,而不会由其父进程终止。这是我的代码:

 #!/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()

这是我的Worker:

 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查看进程。

提问于
用户回答回答于

代码:

import multiprocessing as mp
import time


def main():
    n = 3
    c = list()
    for i in xrange(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('{i} going to sleep'.format(i=i))
    time.sleep(i * 10)
    print('{i} woke up'.format(i=i))


if __name__ == '__main__':
    main()

以上将创建3个进程,每个进程终止10秒。正如代码所示,最后一个进程首先被连接,所以之前终止的另外两个将成为僵尸20秒。你可以看到他们:

ps aux | grep Z

如果进程按照它们将终止的顺序等待,那么将不会有僵尸。删除reversed看到这种情况。但是,在实际应用中,我们很少知道孩子会终止的顺序,所以使用join会导致一些僵尸进程。

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

while True:
    time.sleep(1)
    if not mp.active_children():
        break

所属标签

可能回答问题的人

  • 天使的炫翼

    15 粉丝531 提问35 回答
  • 旺仔小小鹿

    社区 · 运营 (已认证)

    48 粉丝0 提问27 回答
  • 富有想象力的人

    2 粉丝0 提问26 回答
  • 发条丶魔灵1

    6 粉丝525 提问25 回答

扫码关注云+社区

领取腾讯云代金券