Thread
建立子線程 多任務管理
多任務執行形式:
時間片輪轉
優先級調用
CPU狀态
并行:cpu核心數多于運作程式樹
并發:輪換進行程式執行 常态
# 多任務
import threading
import time
def sing():
for i in range(5):
print("正在唱歌...")
time.sleep(1)
def dance():
for i in range(5):
print("正在跳舞...")
time.sleep(1)
def main():
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
print(threading.enumerate())
t1.start()
print(threading.enumerate())
t2.start()
if __name__ == '__main__':
main()
注:target 目标方向
函數名() 調用函數
函數名 顯示函數位置
enumerate 顯示目前線程數量(另 标号用法)
線程之間的關系:
調用start時調用函數并建立子線程,函數結束子線程結束;
函數執行順序不确定,可用time.sleep操作函數執行順序;
子線程結束後主線程才會結束,子線程運作時主線程繼續運作直到需要子線程結果;
join函數使主線程等待子線程結束後繼續進行(除非下一步需要子線程結果,否則一般不用);
守護線程在主線程結束時無論是否結束都強制結束。
函數及類的多線程使用形式:
函數
t=threading.Thread(target=dance)
t.start()
t.join()
注:join 主線程等待子線程完成才繼續運作,一般不用,主線程不用等待子線程
類
class MyThread(threading.Thread):
def run(self):
self.函數名()
t = MyThread()
t.start()
多線程共享全局變量兩種形式
global聲明:變量 global 指向改變
參數為可變類型:實參為清單、集合 指向不變
args傳參 args=(元組,)
**互斥鎖 **
多任務使用全局變量時使用,避免因共享全局變量而産生的資源競争的問題
# 建立鎖
mutex = threading.Lock()
# 鎖定
mutex.acquire()
# 釋放
mutex.release()
死鎖:互鎖
死鎖執行個體
import threading
import time
#建立互斥鎖,預設是沒有上鎖時
mutex_1 = threading.Lock()
mutex_2 = threading.Lock()
def test1():
print("in test1 lock 1")
mutex_1.acquire()
time.sleep(3)
mutex_2.acquire()
print("in test1 step lock 2")
mutex_1.release()
def test2():
print("in test2 lock 2")
mutex_2.acquire()
time.sleep(3)
mutex_1.acquire()
print("in test2 step lock 1")
mutex_1.release()
mutex_2.release()
if __name__ == '__main__':
t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()
結果:
in test1 lock 1
in test2 lock 2
避免死鎖的方法:
1.程式設計時盡量避免(銀行家算法)
2.添加逾時時間(timeout=)
mutex_2.acquire(timeout=1)