信號量


from threading import Semaphore,Thread import timedef func(a,b):time.sleep(1)sem.acquire()print(a+b)sem.release()sem = Semaphore(4) for i in range(10):t = Thread(target=func,args=(i,i+5))t.start()
事件


# 事件被創建的時候,默認為False狀態 # Flase狀態 wait()阻塞 # True 狀態 wait()非阻塞 # clear 設置狀態為False # set 設置狀態位True# 連接數據庫 # 檢測數據庫的可連接情況import time import random from threading import Thread,Eventdef connect_db(e):count = 0while count<3:e.wait(0.5) # 狀態為False的時候,只等待1秒就結束if e.is_set():print('連接數據庫')breakelse:print('第%s次連接失敗'%(count+1))count += 1else:raise TimeoutError('數據庫連接超時')def check_web(e):time.sleep(random.randint(0,3))e.set()e = Event() t1 = Thread(target=connect_db,args=(e,)) t2 = Thread(target=check_web,args=(e,)) t1.start() t2.start()
條件:
條件——鎖
一個條件被創建之初,默認有一個False狀態
False狀態,會影響wait一直處于等待狀態
notify(int數據類型) 制作一串鑰匙


from threading import Condition,Threaddef func(con,i):con.acquire()con.wait()print('在第%s個循環'% i)con.release()con = Condition() for i in range(10):Thread(target=func,args=(con,i)).start() while True:num = int(input('>>>'))con.acquire()con.notify(num)con.release()
定時器


from threading import Timer import time def func():print('時間同步')while True:Timer(2,func).start()time.sleep(2)
隊列


# queue # 隊列的特點:先進先出 # import queue # q = queue.Queue() # q.put() # q.get() # q.put_nowait() # q.get_nowait()# 棧 先進后出 # import queue # q = queue.LifoQueue() # q.put(1) # # q.put(2) # q.put(3) # print(q.get())# 優先級隊列 數值越低優先級越高,優先級一樣按照ASCII碼排 # import queue # q = queue.PriorityQueue() # q.put((20,'a')) # q.put((10,'b')) # q.put((40,'c')) # q.put((2,'e')) # q.put((2,'d')) # print(q.get())
線程池


from concurrent.futures import ThreadPoolExecutor import time def func(n):time.sleep(2)print(n)return n*n def call_back(m):print('結果是:',m.result())tpool = ThreadPoolExecutor(max_workers=5) # 默認 不要超過cpu個數*5 for i in range(20):t = tpool.submit(func,i).add_done_callback(call_back)# tpool.map(func,range(20)) # t_lst = [] # for i in range(20): # t = tpool.submit(func,i) # t_lst.append(t) # # tpool.shutdown() #close+join # print('主線程') # for t in t_lst:print('****',t.result())# 起進程池的話和線程池一模一樣,改個名字就可以了
?