HTB-靶機-Cronos
阿新 • • 發佈:2020-11-02
PyThon 多執行緒
快速入門
先上程式碼
import time import threading # 1 def sing(): for i in range(5): print("1") time.sleep(1) def dance(): for i in range(5): print("2") time.sleep(1) def dance1(): for i in range(5): print("3") time.sleep(1) def dance2(): for i in range(5): print("4") time.sleep(1) def main(): t1 = threading.Thread(target=sing) # 指定函式 t2 = threading.Thread(target=dance) t3 = threading.Thread(target=dance1) t4 = threading.Thread(target=dance2) t1.start() t2.start() t3.start() t4.start() if __name__ == '__main__': main()
結果
進階
指定函式 ===> 動態傳參 ===> 共享全域性變數
資源競爭
1+1=1???
同步就是協同步調﹐按預定的先後次序進行執行。如:你說完﹐我再說·
"同"字從字面上容弟理解為一起動作
其實不是﹐"同"字應是指協同·協助·互相配合。
如程序﹑執行緒同步﹐可理解為程序或執行緒A和B一塊配合﹐A執行到一定程度時要依靠B的某個結果﹐於是停下來﹐示意B執行;B執行﹐再將結果給A;A再繼續操作·
解決執行緒同時修改全域性變數的方式
執行緒同步來進行解決同步出錯而難題:
1.系統呼叫t1﹐然後獲取到g_num的值為0﹐此時上一把鎖﹐即不允許其他執行緒操作g_num2.t1對g_num的值進行+1
3.t1解鎖﹐此時g_num的值為1﹐其他的執行緒就可以使用g_num了﹐而且是g_num的值不是0而是1
4.同理其他執行緒在對g_num進行修改時﹐都要先上鎖﹐處理完後再解鎖﹐在上鎖的整個過程中不允許其
他執行緒訪問﹐就保證了資料的正確性
執行緒同步
互斥鎖
當多個執行緒幾乎同時修改某一個共享資料的時候﹐需要進行同步控制
執行緒同步能夠保證多個執行緒安全訪問競爭資源﹐最簡單的同步機制是引入互斥鎖。
互斥鎖為資源引入—狀態∶鎖定/非鎖定
某個執行緒要更改共享資料時﹐先將其鎖定﹐此時資源的狀態為“鎖定”﹐其他執行緒不能更改﹔直到該執行緒釋放資源﹐將資源的狀態變成“非鎖定”﹐其他的執行緒才能再次鎖定該資源·互斥鎖保證了每次只有一個執行緒進行寫入操作﹐從而保證了多執行緒情況下資料的正確性。
#建立鎖
mutex= threading.Lock()
#鎖定
mutex.acquire()
#釋放
mutex.release()
過程
import threading
import time
# 定義一個全域性變數
g_num = 0
def test1(num):
global g_num
# 上鎖,如果之前沒有被上鎖,那麼此時上鎖成功
# 如果上鎖之前已經被上鎖了,那麼此時會堵塞在這裡,直到這個鎖被解開為止
mutex.acquire()
for i in range(num):
g_num += 1
mutex.release()
print(" - ----in test1 g_num=%d----" % g_num)
def test2(num):
global g_num
mutex.acquire()
for i in range(num):
g_num += 1
mutex.release()
print(" -----in test2 g_num=%d=----" % g_num)
def test3(num):
global g_num
for i in range(num):
mutex.acquire()
g_num += 1
mutex.release()
print(" -----in test3 g_num=%d=----" % g_num)
def test4(num):
global g_num
for i in range(num):
mutex.acquire()
g_num += 1
mutex.release()
print(" -----in test4 g_num=%d=----" % g_num)
# 建立—個互斥鎖,預設是沒有上鎖的
mutex = threading.Lock()
def main():
t1 = threading.Thread(target=test1, args=(1000000,))
t2 = threading.Thread(target=test2, args=(1000000,))
t3 = threading.Thread(target=test1, args=(1000000,))
t4 = threading.Thread(target=test2, args=(1000000,))
t1.start()
t2.start()
time.sleep(2)
print("-----in main Thread g_num = %d---" % g_num)
t3.start()
t4.start()
# 等待上面的2個執行緒執行完畢....
if __name__ == '__main__':
main()
結果
- ----in test1 g_num=1000000----
-----in test2 g_num=2000000=----
-----in main Thread g_num = 2000000---
- ----in test1 g_num=3000000----
-----in test2 g_num=4000000=----
Process finished with exit code 0
# 為什麼?????
死鎖
線上程間共享多個資源的時候﹐如果兩個執行緒分別佔有一部分資源並且同時等待對方的資源﹐就會死鎖。
# coding=utf-8
import threading
import time
class MyThread1(threading.Thread):
def run(self):
# 對mutexA上鎖
mutexA.acquire()
# mutexA上鎖後﹐延時1秒﹐等待另外那個執行緒把mutexB上鎖
print(self.name + '----do1---up--—-')
time.sleep(1)
# 此時會堵塞﹐因為這個mutexB已經被另外的執行緒搶先上鎖了
mutexB.acquire()
print(self.name + '—---do1---down----')
mutexB.release()
# 對mutexA解鎖
mutexA.release()
class MyThread2(threading.Thread):
def run(self):
# 對mutexB上鎖
mutexB.acquire()
# mutexB上鎖後﹐延時1秒·等待另外那個執行緒把mutexA上鎖
print(self.name + '----do2---up----')
time.sleep(1)
# 此時會堵塞﹐因為這個mutexA已經被另外的執行緒搶先上鎖了
mutexA.acquire()
print(self.name + '----do2---down----')
mutexA.release()
# 對mutexB解鎖
mutexB.release()
mutexA = threading.Lock()
mutexB = threading.Lock()
if __name__ == '_main__':
t1 = MyThread1()
t2 = MyThread2()
t1.start()
t2.start()
結果
Thread-1----do1---up----
Thread-2----do2---up----
後期更精彩...