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元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

