我对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
命令的进程。但我真的希望他们一旦完成就被终止。
感谢。
答案 0 :(得分:12)
有几件事:
确保父级joins
为其子级,以避免僵尸。请参阅Python Multiprocessing Kill Processes
您可以检查孩子是否仍在使用is_alive()
成员函数运行。请参阅http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Process
答案 1 :(得分:9)
Using <form id="loginform" action="./functions/dologin.php" method="post">
<input type="hidden" id="xc" name="xc" value="X">
<input type="hidden" id="yc" name="yc" value="X">
<button class="myButton" onclick="getLocation();">Login</button>
</form>
is better than multiprocessing.active_children
. The function Process.join
cleans any zombies created since the last call to active_children
. The method active_children
awaits the selected process. During that time, other processes can terminate and become zombies, but the parent process will not notice, until the awaited method is joined. To see this in action:
join
The above will create 3 processes that terminate 10 second apart each. As the code is, the last process is joined first, so the other two, which terminated earlier, will be zombies for 20 seconds. You can see them with:
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()
There will be no zombies if the processes are awaited in the sequence that they will terminate. Remove the ps aux | grep Z
to see this case. However, in real applications we rarely know the sequence that children will terminate, so using reversed
will result in some zombies.
The alternative join
does not leave any zombies.
In the above example, replace the loop active_children
with:
for p in reversed(c):
and see what happens.
答案 2 :(得分:1)
使用active_children。 multiprocessing.active_children