我正在编写一个python脚本,它将通过向不同进程发送行来快速解析文件。最后,我希望父级从每个子进程接收结果,然后能够操作它。这是代码:
#!/usr/bin/env python
import os
import re
from datetime import datetime
from multiprocessing import Process, JoinableQueue
class LineConsumer(Process):
def __init__(self, queue):
self.queue = queue
self.lines = 0
super(LineConsumer, self).__init__( )
def run(self):
print "My PID is %d" % self.pid
while True:
line = self.queue.get( )
print self.lines
if ':' in line:
self.lines += 1
self.queue.task_done( )
class Parser(object):
def __init__(self, filename, processes=4):
self.filename = filename
self.processes = processes
def parse(self):
queue = JoinableQueue(100)
consumers = [ ]
parents = [ ]
for i in range(0, self.processes):
lc = LineConsumer(queue)
lc.start( )
consumers.append(lc)
starttime = datetime.now( )
problem = False
numlines = 0
with open(self.filename, 'r') as data:
for line in data:
numlines += 1
def checkAlive(p):
if not p.is_alive( ):
return False
return True
alive = map(checkAlive, consumers)
if False in alive:
problem = True
print "A process died!!!"
break
queue.put(line)
if not problem:
queue.join( )
for p in consumers:
print p.lines( )
p.terminate( )
p.join( )
endtime = datetime.now( )
timedelta = endtime - starttime
lps = numlines / timedelta.total_seconds( )
print "Processed packets at %f lps" % lps
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
print "Supply a file to read"
sys.exit(1)
parser = Parser(sys.argv[1])
parser.parse( )
结果如下:
My PID is 11578
My PID is 11579
My PID is 11580
My PID is 11581
0
1
0
2
1
3
2
1
...
555
627
564
556
628
0
0
0
0
Processed packets at 27189.771341 lps
正如您所看到的,每个孩子都可以保存其行数,但是当我尝试从父母访问计数时,我会一直得到0.如何将行数发送给父母?
答案 0 :(得分:3)
您可以将值传递回结果队列。
在LineConsumer:
def __init__(self, queue, result_queue):
self.result_queue = result_queue
# ...
def terminate(self):
self.results_queue.put(self.lines)
super(LineConsumer, self).terminate()
在Parser中:
queue = JoinableQueue(100)
result_queue = Queue()
# ...
lc = LineConsumer(queue, result_queue)
# ...
for p in consumers:
p.terminate()
p.join()
while True:
try:
print results.queue.get(False)
except Queue.Empty: # need to import Queue
break
答案 1 :(得分:0)
我想问题是你正在尝试访问其他进程(子进程)中实际更改的对象副本。您需要使用显式进程间通信将响应发送回父级。即像你用来向儿童传递信息的JoinableQueue
之类的东西。