在python中,常用的多線程的模塊有這么幾個
- _thread
- threading
- Queue
之前有個 thread 模塊,被 python3 拋棄了,改名為 _thread。
但其實 _thread 也沒什么人用,因為 _thread 有的 threading 都有,_thread 沒有的 threading 依然有。
那么接下來我們就來嘗試 threading 吧
示例
每天得摸 20 條魚,每隔一秒鍾摸一條,也就是這樣
import time def moyu_time(name, delay, counter): while counter: time.sleep(delay) print("%s 開始摸魚 %s" % (name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) counter -= 1 if __name__ == '__main__': moyu_time('rogn',1,20)
但是,現在我們知道了多線程,就可以找人幫忙一起摸魚,
import time import threading # 創建一個線程子類 class MyThread(threading.Thread): def __init__(self,threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print("開始線程:" + self.name) moyu_time(self.name, self.counter, 10) print("退出線程:" + self.name) def moyu_time(name, delay, counter): while counter: time.sleep(delay) print("%s 開始摸魚 %s" % (name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) counter -= 1 if __name__ == '__main__': # 創建新線程 # 讓小明摸一次魚休息1秒鍾 # 讓小紅摸一次魚休息2秒鍾 thread1 = MyThread(1, "小明", 1) thread2 = MyThread(2, "小紅", 2) # 開啟新線程 thread1.start() thread2.start() # 等待至線程中止 thread1.join() thread2.join() print ("退出主線程")
在這里,我們創建了一個線程類,它繼承了 threading.Thread。在我們這個線程類里面定義了一個 run 方法,這個 run 方法去調用了摸魚的方法。
可以看到我們創建了兩個線程,一個叫小明線程,一個叫小紅線程,當我們的線程調用 start 方法的時候它們就會去執行 run 方法。
因為頻繁的創建線程 銷毀線程,非常的浪費資源,所以我們創建線程池,通過線程池就可以重復利用線程。
在 python 中,可以使用 ThreadPoolExecutor 來實現線程池,
import time from concurrent.futures import ThreadPoolExecutor def moyu_time(name, delay, counter): while counter: time.sleep(delay) print("%s 開始摸魚 %s" % (name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) counter -= 1 if __name__ == '__main__': pool = ThreadPoolExecutor(10) for i in range(1,5): pool.submit(moyu_time('rogn'+str(i),1,3))
我們還可以用一個叫做 Queue 的隊列來創建線程池,最常用的方法就是 put 和 get 了。
我們創建一個長度為 6 的隊列,接着根據隊列的長度創建了線程,每個線程都讓它們處於守護狀態,也就是需要的時候能馬上執行:
def queue_pool(): queue = Queue(6) for i in range(queue.maxsize): t = CustomThread(queue) t.setDaemon(True) t.start()
接着我們就可以用 put 方法,把我們想做的事情往隊列里面塞,比如這里我們想要摸魚:
for i in range(20): queue.put(moyu) queue.join()
完整代碼如下:
import threading import time from queue import Queue class CustomThread(threading.Thread): def __init__(self, queue): threading.Thread.__init__(self) self.__queue = queue def run(self): while True: q_method = self.__queue.get() q_method() self.__queue.task_done() def moyu(): print(" 開始摸魚 %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) def queue_pool(): queue = Queue(5) for i in range(queue.maxsize): t = CustomThread(queue) t.setDaemon(True) t.start() for i in range(20): queue.put(moyu) queue.join() if __name__ == '__main__': queue_pool()