1. 程式人生 > >Python隊列與多線程及文件鎖

Python隊列與多線程及文件鎖

元素 .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_name

    
def 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隊列與多線程及文件鎖