Python中对队列和线程的操作,需要使用模块:Queue 和 threading。其中,Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。
简单的研究了一下使用方法,写了一个小例子,代码如下:
1 #!/bin/env python 2 #coding=utf-8 3 4 import os 5 import sys 6 import threading 7 import time 8 import Queue 9 10 global g_thread_num 11 global g_pages_queue 12 13 14 class Parser(threading.Thread): 15 def __init__(self, threadname, pagequeue): 16 17 threading.Thread.__init__(self, name = threadname) 18 19 self.queue = pagequeue 20 21 def run(self): 22 print("Parser::thread running...") 23 24 while True: 25 if self.queue.empty(): 26 break 27 else: 28 time.sleep(0.05) 29 page_file = self.queue.get() 30 31 #do some thing here 32 print self.name, self.ident, page_file 33 34 self.queue.task_done() 35 36 time.sleep(0.05) 37 38 return 39 40 41 def GetPagesFromFile(file_name): 42 if len(file_name) == 0 or file_name == None: 43 print("GetPagesFromFile::input file is null") 44 sys.exit(-1) 45 46 fp = open(file_name) 47 for url in fp.readlines(): 48 g_pages_queue.put(url.strip('\n')) 49 fp.close() 50 51 return g_pages_queue.qsize() 52 53 54 55 56 def RunFileInterface(file_name): 57 if len(file_name) == 0: 58 return 59 60 page_nb = GetPagesFromFile(file_name) 61 print page_nb 62 63 for i in range(g_thread_num): 64 65 parser = Parser("parser " + str(i), g_pages_queue) 66 67 parser.daemon = True 68 69 parser.start() 70 71 #parser.join() 72 73 g_pages_queue.join() 74 75 print("RunFileInterface::Done......") 76 77 return 78 79 80 81 if __name__ == '__main__': 82 83 84 g_thread_num = 2 85 86 g_pages_queue = Queue.Queue() 87 88 if len(sys.argv) == 2 and sys.argv[1] == '-db': 89 90 print("Main::Run DB Interface!") 91 92 #RunDBInterface() 93 94 elif len(sys.argv) >= 2 and sys.argv[1] == '-f': 95 page_files = "" 96 if len(sys.argv) == 3: 97 page_files = str(sys.argv[2]) 98 99 if os.path.exists(page_files) and os.path.isfile(page_files): 100 101 print("Main::Run File Interface!") 102 103 RunFileInterface(page_files) 104 105 else: 106 print("Main::File Not Exists!") 107 108 sys.exit(0)
功能:从文件中读取每一行,放入队列中,用线程输出
需要注意的几点:
1、"parser.daemon = True" 必须在线程Start之前使用,否则可能出现RuntimeError异常。它的初始值是从主线程继承的,主线程一般不是守护线程,所以它的默认值为False
2、每次从Queue中取出一个元素,处理完成之后,最好调用一下"Queue.task_done()"
参考资料:
1、http://docs.python.org/2/library/queue.html
2、http://docs.python.org/2/library/threading.html
3、http://www.ibm.com/developerworks/cn/aix/library/au-threadingpython/
4、http://www.2cto.com/kf/201109/104515.html
5、http://www.cnblogs.com/holbrook/archive/2012/03/15/2398060.html
6、http://developer.51cto.com/art/201003/186160.htm