Python隊列與多線程及文件鎖
阿新 • • 發佈:2018-11-14
元素 .data 就會 python col 執行 混亂 pre join()
隊列實現生產-多線程消費
先看代碼
# -*- coding: utf-8 -*- import queue import threading mu = threading.Lock() class Producer(threading.Thread): def __init__(self, data_queue, thread_name): super(Producer, self).__init__() self.data_queue = data_queue self.thread_name = thread_namedef run(self): for i in range(30): self.data_queue.put(i) print "完成生產:{}".format(i) class Customer(threading.Thread): def __init__(self, data_queue, thread_name): super(Customer, self).__init__() self.data_queue = data_queue self.thread_name= thread_name def run(self): while True: if mu.acquire(True): try: data = self.data_queue.get(True, 3) print "%s完成消費: %s" % (self.thread_name, data) with open(‘ax.txt‘, ‘a+‘) as f: f.write(‘customer_‘+str(data)+‘\n‘) except: self.data_queue.task_done() break mu.release() q = queue.Queue() producer = Producer(q, ‘Pro‘) producer.start() producer.join() threads = [] for i in range(1, 5): name = ‘Cus{}‘.format(i) customer = Customer(q, name) customer.start() threads.append(customer) for j in threads: j.join()
Python隊列使用的是queue模塊,多線程使用的是threading模塊
生產者:Producer類,不斷的向隊列中添加元素,這裏是添加數字1-30.
消費者:Customer類,創建4個線程,然後不斷的從隊列中取出元素進行“消費”。
這裏有兩個註重點:
1)寫操作,因為這裏是要寫入文件的,所以,如果不加鎖的話,就會出現順序混亂,可能會覆蓋數據的情況。
對此,可以先創建一個鎖,進行寫操作時就加上鎖,完成後釋放鎖
# 創建鎖 mu = threading.Lock() # 加鎖 mu.acquire() # 釋放鎖 mu.release()
2) 線程退出,當隊列為空時,我想要退出線程結束。如果不做點東西(超時設置),線程就會一直想要從隊列獲取元素而阻塞,不會退出。
所以,從隊列獲取元素時設置超時時間,超時後會引發異常。上面代碼 self.data_queue.get(True, 3) 設置了超時時間為3秒,當隊列為空後超過3秒,就會引發異常,執行
self.data_queue.task_done(),task_done()函數會給線程發送信號,後續的 join() 函數才會生效,退出線程。
Python隊列與多線程及文件鎖