簡體   English   中英

如何殺死多處理模塊創建的僵屍進程?

[英]how to kill zombie processes created by multiprocessing module?

我是multiprocessing模塊的新手。 我只是嘗試創建以下內容:我有一個進程,其工作是從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()

這是我的工人:

 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命令查看進程。 但我真的希望他們一旦完成就被終止。 謝謝。

有幾件事:

  1. 確保父級joins其子級,以避免僵屍。 請參閱Python多處理程序殺死進程

  2. 您可以使用is_alive()成員函數檢查子項是否仍在運行。 請參見http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Process

使用multiprocessing.active_childrenProcess.join更好。 函數active_children清除自上次調用active_children以來創建的任何僵屍。 join方法等待所選進程。 在此期間,其他進程可以終止並變為僵屍,但在等待等待的方法加入之前,父進程將不會注意到。 要看到這個:

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):代替for p in reversed(c):的循環for p in reversed(c): with:

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

看看會發生什么。

使用active_children。 multiprocessing.active_children

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM