一、互斥鎖:
1.線程同步能夠保證多個線程安全訪問競爭資源,最簡單的同步機制是引入互斥鎖。
2.互斥鎖為資源引入一個狀態:鎖定、非鎖定
3.某個線程要更改共享數據是,先將其鎖定。此時資源的狀態為鎖定,其他線程不能更改知道該
線程釋放資源,將資源的狀態編程"非鎖定",其他的線程才能再次鎖定該資源
4.互斥鎖保證了每次只有一個線程進行寫入操作,從而保證了多線程情況下數據的正確性。
例子:
創建鎖
suo = threading.LOck()
鎖定
suo.acquire()
非鎖定釋放
suo.release()
例子:
import threading
count = 0
def line1():
"""
函數1
:return:
"""
global count
global lock
for i in range(100000):
lock.acquire()
count += 1
lock.release()
def line2():
"""
函數2
:return:
"""
global count
global lock
for i in range(100000):
lock.acquire()
count += 1
lock.release()
lock = threading.Lock() # 創建鎖
thread1 = threading.Thread(target=line1) # 創建線程
thread2 = threading.Thread(target=line1) # 創建線程
thread1.start() # 線程開始
thread2.start() # 線程開始
thread1.join() # 阻塞線程
thread2.join() # 阻塞線程
print(count)
二、死鎖
在線程間共享多個資源的時候,如果兩個線程分別占有一部分資源並且同時等待對方的資源,就會
造成死鎖‘盡管死鎖很少發生,但一旦發生就會造成應用的停止響應。
三、GIL 全局解釋器鎖:、
因為全局解釋器鎖的原因,保證了python在運行的時候一次只能運行一個線程,而做不到線程
的並行,一個線程執行完了才能接着執行下一線程。(線程只能並發不能並行)
我們可以使用多進程來實現程序的並行。
問題一: python單線程和多線程分別來完成工作,到底那個快?
1.io密集型:涉及到網絡、磁盤io的任務都是io密集型任務,這類任務的特點是cpu消耗很少,任務的大部分的
時間都在等待io操作完成(因為io的速度遠遠低於cpu和內訓的速度)
結論:io密集型操作,多線程比單線程要快
2.cpu密集型:cpu密集型也稱為計算密集型,任務的特點是要進行大量的計算,消耗cpu資源,比如
計算圓周率、對視頻進行高清解碼等等,全靠cpu的運算能力
結論:cpu密集型操作,單線程比多線程要快
四、隊列
1.Python的Queue模塊中提供了同步的、線程安全的隊列,這些隊列都實現了鎖原語,能夠在多線程中直接
使用。可以使用隊列來實現線程間的同步。
2.初始化Queue()對象時,若括號中沒有指定最大可接收的消息數量,或數量為負值,那么就代表可
接受的消息數量沒有上限。
隊列的方法:
task_done() 在隊列中每獲取一個數據,就要發送一個標記
join() 判斷隊列中的任務是否執行完畢,如果沒有執行完畢,會一直等待。
qsize() 返回當前隊列包含的消息數量;
empty() 判斷隊列是否為空 ,返回True 或 False
full() 判斷隊列是否為滿了 ,返回True 或 False
put() 添加隊列,如果隊列數據達到上限,就不能再添加。
get() 獲取隊列,如果隊列數據為空,就不能在獲取
put_nowait() 添加隊列不等待
get_nowait() 獲取隊列不等待
1.FIFO(先入先出)隊列
from queue import Queue
2.LIFO后入先出
from queue import LifoQueue
3.優先級隊列 PriorityQueue
from queue import PriorityQueue
優先級隊列,以優先級順序(最低優先級)檢索打開條目的隊列的變體。
條目通常是表單的元組:(優先number, data)
注意:這三個模塊都有上面九個方法