python多線程和線程池


在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()

 

 

參考鏈接:https://zhuanlan.zhihu.com/p/58925023


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM