py

作者: sustainer123 (caster)   2024-09-26 18:12:57
線程(Thread)
線程是進程中執行任務的最小單位
一個進程至少有一個線程 也有可能有多個線程
舉個具體的例子
進程就像一間工廠
線程是裡面的工人 多線程就是一間工廠有多個工人
工人負責執行任務
多線程(MultiThreading)
多線程就是一個進程裡面用多個線程
python用threading編寫多線程
調用thread類創建新線程
thread類的參數跟process差不多
target代表目標函數 args代表傳入參數 kwargs傳入關鍵字參數
name是標記thread名稱
相關方法也差不多
啟動是用start 等待用join
我想補充說明run()跟start()的差別
process也有一樣的東西
py:
import threading
def print_current_thread():
current = threading.current_thread()
print(f"Current thread: {current}")
t1 = threading.Thread(target=print_current_thread)
t1.run()
t2 = threading.Thread(target=print_current_thread)
t2.start()
t2.join()
輸出:
Current thread: <_MainThread(MainThread, started 14028)>
Current thread: <Thread(Thread-2 (print_current_thread), started 20984)>
從輸出結果 我們可以發現run是直接執行當前線程 start才會啟動新線程並執行
process的run跟start也有相同差異
再來說明lock
多線程與多進程最大差異在於資源共用
多進程會把整包東西複製到子進程
多線程則會共用資源 包括變數
所以會發生下面的問題:
import time, threading
# 假定这是你的银行存款:
balance = 0
def change_it(n):
# 先存后取,结果应该为0:
global balance
balance = balance + n
balance = balance - n
def run_thread(n):
for i in range(10000000):
change_it(n)
t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)
這程式碼是兩個線程對balance做加減
理論上 這結果是0
但實際並非如此
python中一行程式碼傳到cpu
諸如 balance = balance + n
往底層走會變成:
x為臨時變量
x = balance + n
balance = x
所以放回原本程式碼
兩個線程交錯就可能變成:
初始值 balance = 0
t1: x1 = balance + 5 # x1 = 0 + 5 = 5
t2: x2 = balance + 8 # x2 = 0 + 8 = 8
t2: balance = x2 # balance = 8
t1: balance = x1 # balance = 5
t1: x1 = balance - 5 # x1 = 5 - 5 = 0
t1: balance = x1 # balance = 0
t2: x2 = balance - 8 # x2 = 0 - 8 = -8
t2: balance = x2 # balance = -8
结果 balance = -8
線程的問題大致是這樣
所以我們就要加個鎖
balance = 0
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要释放锁:
lock.release()
鎖的函數跟process差不多 不另行說明
大致這樣ㄅ gil之後再說 先吃飯
參考資料:
https://liaoxuefeng.com/books/python/process-thread/thread/index.html
https://docs.python.org/3/library/threading.html#rlock-objects
作者: cities516 (安安路過)   2024-09-26 18:14:00
我記得multi thread跟multi process鎖法剛好相反一個是一邊跑另一邊鎖 另一個是兩邊一起跑
作者: sustainer123 (caster)   2024-09-26 18:15:00
py thread有gil鎖 只要用cpython都會這樣multi thread實際上只會跑一個我有看到加c的擴充處理這問題 但好麻煩另一種就Coroutine+multi processㄅ

Links booklink

Contact Us: admin [ a t ] ucptt.com