py

看板Marginalman作者 (溫水佳樹的兄長大人)時間1年前 (2024/09/26 18:13), 編輯推噓0(006)
留言6則, 2人參與, 1年前最新討論串8/16 (看更多)
線程(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 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.119.233.6 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Marginalman/M.1727345582.A.BBB.html

09/26 18:14, 1年前 , 1F
我記得multi thread跟multi process鎖法剛好相反
09/26 18:14, 1F

09/26 18:14, 1年前 , 2F
一個是一邊跑另一邊鎖 另一個是兩邊一起跑
09/26 18:14, 2F

09/26 18:15, 1年前 , 3F
py thread有gil鎖 只要用cpython都會這樣
09/26 18:15, 3F

09/26 18:16, 1年前 , 4F
multi thread實際上只會跑一個
09/26 18:16, 4F

09/26 18:16, 1年前 , 5F
我有看到加c的擴充處理這問題 但好麻煩
09/26 18:16, 5F

09/26 18:17, 1年前 , 6F
另一種就Coroutine+multi processㄅ
09/26 18:17, 6F
文章代碼(AID): #1czJEkkx (Marginalman)
討論串 (同標題文章)
完整討論串 (本文為第 8 之 16 篇):
1
5
9月前, 03/09
2
3
1年前, 11/16
0
3
1年前, 11/12
2
2
1年前, 10/02
6
13
1
1
1年前, 09/28
1
1
2
6
0
6
1年前, 09/26
1
7
文章代碼(AID): #1czJEkkx (Marginalman)