1. 鎖:Lock (1次放1個)同步鎖
線程安全,多線程操作時,內部會讓所有線程排隊處理。如:list/dict/Queue
線程不安全 + 人 => 排隊處理。
需求:
a. 創建100個線程,在列表中追加8
b. 創建100個線程
v = []
鎖
- 把自己的添加到列表中。
- 在讀取列表的最后一個。
解鎖
以后鎖一個代碼塊:
import threading import time v = [] lock = threading.Lock() def func(arg): lock.acquire() # 鎖的區域--------- v.append(arg) # ---------------- time.sleep(0.01) # ---------------- m = v[-1] # ----------------- print (arg,m) # ---------------- lock.release() # ---------鎖的區域 for i in range(10 ): t =threading.Thread(target=func,args= (i,)) t.start()
?
2. 鎖:RLock (1次放1個)遞歸鎖
支持鎖多次,解多次
import threading import time v = [] lock = threading.RLock() # 參數是鎖的數量 def func(arg): lock.acquire() # 加幾次鎖,下面就釋放幾次,lock不支持多次鎖,Rlock支持 lock.acquire() v.append(arg) time.sleep( 0.01 ) m = v[-1 ] print (arg,m) lock.release() lock.release() for i in range(10 ): t =threading.Thread(target=func,args= (i,)) t.start()
3. 鎖:BoundedSemaphore(1次放N個)信號量
import time import threading lock = threading.BoundedSemaphore(3 ) def func(arg): lock.acquire() print (arg) time.sleep( 1 ) lock.release() for i in range(20 ): t =threading.Thread(target=func,args= (i,)) t.start()
?
4. 鎖:Condition(每次釋放前需要輸入要釋放的個數x)
import time import threading lock = threading.Condition() # ############# 方式一 ############## def func(arg): print ( ' 線程進來了 ' ) lock.acquire() lock.wait() # 加鎖 print (arg) time.sleep( 1 ) lock.release() for i in range(10 ): t =threading.Thread(target=func,args= (i,)) t.start() while True: inp = int(input( ' >>> ' )) lock.acquire() lock.notify(inp) lock.release() # ############# 方式二 ############## def xxxx(): print ( ' 來執行函數了 ' ) input( " >>> " ) # 讓每一個線程完成某個條件,完成之后釋放 # ct = threading.current_thread() # 獲取當前線程 # ct.getName() return True def func(arg): print ( ' 線程進來了 ' ) lock.wait_for(xxxx) print (arg) time.sleep( 1 ) for i in range(10 ): t =threading.Thread(target=func,args= (i,)) t.start()
?
5. 鎖:Event(1次放所有)
import time import threading lock = threading.Event() def func(arg): print ( ' 線程來了 ' ) lock.wait() # 加鎖:紅燈 print (arg) for i in range(10 ): t =threading.Thread(target=func,args= (i,)) t.start() input( " >>>> " ) lock.set() # 綠燈 lock.clear() # 再次變紅燈 for i in range(10 ): t =threading.Thread(target=func,args= (i,)) t.start() input( " >>>> " ) lock.set()
?
總結:
線程安全,指的是容器存放數據的時候線程安全;列表和字典線程安全;
為什么要加鎖?
- 非線程安全
- 控制一段代碼
6. threading.local
作用:
內部自動為每個線程維護一個空間(字典),用于當前存取屬于自己的值。保證線程之間的數據隔離。
{
線程ID: {...}
線程ID: {...}
線程ID: {...}
線程ID: {...}
}
示例:
import time
import threading
v = threading.local()
def func(arg):
# 內部會為當前線程創建一個空間用于存儲:phone=自己的值
v.phone = arg
time.sleep(2)
print(v.phone,arg) # 去當前線程自己空間取值
for i in range(10):
t =threading.Thread(target=func,args=(i,))
t.start()
7. 線程池
最多能創建多少個線程
創建多個線程用線程池,避免無節制創建線程
from concurrent.futures import ThreadPoolExecutor import time def task(a1,a2): time.sleep( 2 ) print (a1,a2) # 創建了一個線程池(最多5個線程) pool = ThreadPoolExecutor(5 ) for i in range(40 ): # 去線程池中申請一個線程,讓線程執行task函數。 pool.submit(task,i,8)
?
8. 生產者消費者模型
三部件:
生產者
隊列,先進先出
擴展: 棧,后進先出
消費者
問:生產者消費者模型解決了什么問題?不用一直等待的問題。
示例:
import time import queue import threading q = queue.Queue() # 線程安全 def producer(id): """ 生產者 """ while True: time.sleep( 2 ) q.put( ' 包子 ' ) print ( ' 廚師%s 生產了一個包子 ' % id ) for i in range(1,4 ): t = threading.Thread(target=producer,args= (i,)) t.start() def consumer(id): """ 消費者 """ while True: time.sleep( 1 ) v1 = q.get() print ( ' 顧客 %s 吃了一個包子 ' % id) for i in range(1,3 ): t = threading.Thread(target=consumer,args= (i,)) t.start()
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
