並發編程之線程
一、進程創建的機制
進程是計算機中最小的資源分配單位
進程對於操作系統來說還是有一定的負擔
創建一個進程,操作系統要分配的資源大致:代碼、數據、文件
存放代碼到內存,存儲數據到內存空間,文件,系統分配需要時間,占用的空間也比較大
二、線程
隨著對並發的要求越來越高,無限開啟進程是不現實的,解決高並發下進程的問題,使用線程。
線程是輕量級的概念,它沒有屬於自己的進程資源
一條線程只負責執行代碼,沒有自己獨立的代碼、變量、文件資源,線程都是共享資源
線程是計算機中被CPU調度的最小單位,計算機當中的CPU都是執行線程中的代碼
三、進程和線程之間的關系
每一個進程中都有至少一條線程在工作,一個進程可以有多個線程
四、線程的特點:
① 同一個進程中的所有線程的內存空間、資源都是共享的
② 輕量級,沒有自己的資源
③ 線程之間的切換很近,也很快,進程之間切換比較慢,進程占用資源多
④ 輕型實體
⑤ 獨立調度和分配的基本單位
⑥ 共享進程資源
⑦ 並發執行
五、線程的分類
用戶級線程:操作線程,操作系統的內核只能通過進程去執行線程
內核級線程:操作系統能夠直接調度線程
混合實現:用戶能查看調度線程,內核也能調度線程
六、進程和線程之間的區別
① 占用的資源
② 調度的效率
③ 資源是否共享
七、python中的線程
一個線程中的多個線程不能並線,由於python是解釋型語言,所有的解釋型語言都不能並行多個進程。
GIL鎖:全局解釋器鎖,為了線程的安全
由於CPython解釋器的原因,內部有一個全局解釋器鎖,所以線程不能充分的利用多核,只能同一時刻同一個進程中的線程只有一個能被CPU執行
GIL鎖目前是能夠提高線程切換的效率,但也確實限制了程序的效率
八、線程的創建
Thread模塊比較老,Threading模塊比較新,而且更高級,兩個模塊不能一起使用
import os from threading import Thread def func(): print(‘子線程‘,os.getpid()) print(‘主線程‘,os.getpid()) for i in range(2): t= Thread(target=func) # 創建子線程 t.start() ‘‘‘ 主線程 8076 子線程 8076 子線程 8076 ‘‘‘
輕量級
線程比進程的運行效率高
import os,time from multiprocessing import Process from threading import Thread def func(): print(‘進程號:‘,os.getpid()) if __name__ == ‘__main__‘: # 創建線程 start = time.time() t_lis = [] for i in range(100): t = Thread(target=func) t.start() t_lis.append(t) for t in t_lis:t.join() # 保障線程全部執行完畢 tt = time.time() - start # 創建進程 start = time.time() p_lis = [] for i in range(100): p = Process(target=func) p.start() p_lis.append(p) for p in p_lis:p.join() pt = time.time() - start print(tt,pt) # 統計線程和進程所運行的時間 # 0.02799248695373535 2.422297239303589
數據共享
from threading import Thread count = 100 def func(): global count count -= 1 t_lis = [] for i in range(100): t = Thread(target=func) t.start() t_lis.append(t) for t in t_lis:t.join() print(count) # 0
並發編程之線程