更新:在 dano 的帮助下,我解决了这个问题。
我没有使用join()
调用生产者,它使我的脚本挂起。
只需添加一行就像dano所说:
...
producer = multiprocessing.Process(target=produce,args=(file_queue,row_queue))
producer.daemon = True
producer.start()
...
旧脚本:
import multiprocessing
import Queue
QUEUE_SIZE = 2000
def produce(file_queue, row_queue,):
while not file_queue.empty():
src_file = file_queue.get()
zip_reader = gzip.open(src_file, 'rb')
try:
csv_reader = csv.reader(zip_reader, delimiter=SDP_DELIMITER)
for row in csv_reader:
new_row = process_sdp_row(row)
if new_row:
row_queue.put(new_row)
finally:
zip_reader.close()
def consume(row_queue):
'''processes all rows, once queue is empty, break the infinit loop'''
while True:
try:
# takes a row from queue and process it
pass
except multiprocessing.TimeoutError as toe:
print "timeout, all rows have been processed, quit."
break
except Queue.Empty:
print "all rows have been processed, quit."
break
except Exception as e:
print "critical error"
print e
break
def main(args):
file_queue = multiprocessing.Queue()
row_queue = multiprocessing.Queue(QUEUE_SIZE)
file_queue.put(file1)
file_queue.put(file2)
file_queue.put(file3)
# starts 3 producers
for i in xrange(4):
producer = multiprocessing.Process(target=produce,args=(file_queue,row_queue))
producer.start()
# starts 1 consumer
consumer = multiprocessing.Process(target=consume,args=(row_queue,))
consumer.start()
# blocks main thread until consumer process finished
consumer.join()
# prints statistics results after consumer is done
sys.exit(0)
if __name__ == "__main__":
main(sys.argv[1:])
目的:
我正在使用python 2.7
multiprocessing
生成3个同时读取3个文件的生产者,然后将文件行放入row_queue
并生成1个消费者以进行更多处理所有行。消费者完成后,打印统计信息会产生主线程,因此我使用join()
方法。最后调用sys.exit(0)
退出脚本。
问题: 无法退出脚本。
我尝试将sys.exit(0)
替换为print "the end"
,"结束"显示在控制台上。难道我做错了什么?脚本为什么不退出,以及如何让它退出?感谢
答案 0 :(得分:1)
您的producers
没有multiprocessing.Process.daemon
设置:
<强>守护程序强>
进程的守护进程标志,一个布尔值。必须在调用start()之前设置它。
初始值继承自创建过程。
当进程退出时,它会尝试终止所有守护进程子进程。
请注意,不允许守护进程创建子进程。否则,守护进程会在子进程退出时终止其子进程。此外,这些不是Unix守护程序或服务,它们是正常进程,如果非守护进程已退出,它们将被终止(并且不会被连接)。
https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Process.daemon
只需添加producer.daemon = True
:
...
producer = multiprocessing.Process(target=produce,args=(file_queue,row_queue))
producer.daemon = True
producer.start()
...
这应该使整个程序在consumer
加入时结束。
顺便说一句,你也应该join
生产者。