一. 線程隊列
引入線程隊列 : import queue #和普通隊列引入方法相同
線程隊列方法 :
q = queue.Queue() #實例化對列,先進先出
q = queue.LifoQueue() #實例化隊列,后進先出 ( Last in, first out )
q = queue.PriorityQueue() #實例化隊列,優先級隊列
優先級隊列,put() 方法接收的是一個元組,第一個元素是優先級,第二個元素是數據
優先級如果為數字,按照數字大小比較
如果優先級是字符串或特殊字符,按照字符串或特殊字符的ASCII碼比較,如果ASCII碼相同,按照先進先出原則取出
import queue # q = queue.Queue()#先進先出 # q.put(1) # q.put(2) # q.put(3) # q.put(4) # print(q.get()) # q = queue.LifoQueue()#后進先出 # q.put(1) # q.put(2) # q.put(3) # q.put(4) # print(q.get()) q = queue.PriorityQueue()#優先級隊列, q.put((1,'11'))#優先級隊列添加的參數是一個元組,元組元素為優先 q.put((2,'22')) q.put((3,'33')) q.put((4,'44')) print(q.get())
二. 線程池
import time from concurrent.futures import ThreadPoolExecutor def func(num): time.sleep(0.5) print(num) return num*num #將num*num返回給方法調用者,也就是submit,用t_r接收 t = ThreadPoolExecutor(5) #多線程最大設置數量應該為os.cpu_count()的五倍,盡量不要多 lst = [] for i in range(10): t_r = t.submit(func,i) #提交任務,參數 :第一次參數為要執行的任務,第二個參數為給任務傳的參數和進程池不同的是線程池參數傳遞不需要在寫(args= ),直接寫參數就好 lst.append(t_r) #將任務返回的結果添加到一個列表中 t.shutdown() #相當於進程的close + join 等待子線程執行完再執行主線程 print('主線程') [print(i.result()) for i in lst] #對列表進行循環,用result()方法取出,取出的是計算后的結果,並且順序和for循環相同
################################map方法##############################
import time from concurrent.futures import ThreadPoolExecutor def func(num): time.sleep(0.5) print(num) return num*num
t = ThreadPoolExecutor(5) t.map(func,range(20))#拿不到返回值,拿到的是生成器. 提交多個任務,相當於for+submit() t.shutdown() print('主線程')
##########################回調函數############################
將普通函數的返回值自動傳給回調函數處理,線程池中的回調函數時子線程調用的
def func(num): time.sleep(0.5) print(num) return num*num def call_back(n): print('回調函數 : ',n.result()) t = ThreadPoolExecutor(5) lst = [] for i in range(10): t.submit(func,i).add_done_callback(call_back)#創建回調函數,和進程的創建不同