程序:指令和數據的有序集合,一個可運行文件
進程:一段程序的執行過程
進程的三種狀態:就緒態,運行態,阻塞態
就緒態:獲取了除CPU外的其他所有資源,只要處理器分配資源就可以立馬執行
運行態:獲取處理器資源,程序開始執行
阻塞態:等待條件滿足才能運行的狀態,如等待I/0操作
線程:通常,一個進程中包含多個線程,線程可以利用進程中的所有資源,線程作爲獨立運行、獨立調度的基本單位,爲進程
中的 一個函數;
多線程:爲了同步完成多項任務,不是爲了提高運行效率,而是爲了提高資源使用效率來提高系統的效率;線程是同一時間需
要完成多項任務的時候實現的;
進程與線程的區別:進程在執行過程擁有獨立的內存單元,而多線程共享內存
子線程:程序執行時,程序本身就是一個線程,爲主線程,手動創建的線程爲子線程,主線程執行過程中,不會等待子線程
代碼 |
運行結果
|
import threading import time start=time.time() def myprint(name): curstart=time.time() time.sleep(5) print(name,'線程執行了') end=time.time() print(name,'開始時間',curstart-start,'結束時間',end-start) # 程序執行時,程序本身就是一個線程,爲主線程 # 手動創建的線程爲子線程 # 主線程執行過程中,不會等待子線程 t1=threading.Thread(target=myprint,args=['thread1',]) t2=threading.Thread(target=myprint,args=['thread2',]) t3=threading.Thread(target=myprint,args=['thread3',]) #方法1 t1.start() t1.join() #進行線程阻塞,當t1線程執行結束後,啓用t2 t2.start() t2.join() t3.start() t3.join() end=time.time() print('主線程執行完畢',end-start) #方法2 t1.start() t2.start() t3.start() t1.join() t2.join() t3.join() end=time.time() print('主線程執行完畢',end-start) |
1.每個線程啓動後,緊跟着阻塞線程,相當於程序按順序執行多個線程,效果認爲單線程 程序運行總時長爲:15s
thread1 線程執行了
2.先啓用所有需要同時執行的線程,然後阻塞所有線程,大大節約程序運行時間,發揮多線程功能; 程序運行總時長爲:5s thread1 線程執行了
|
線程鎖(互斥鎖):
當多個線程對統一段內存地址的數據進行修改時,會發生錯亂的情況,
import threading
import time
lock=threading.Lock() #創建線程鎖
num=100
def myprint(name):
lock.acquire() # 獲取鎖,用於線程同步
global num
num=num-1
print(name,'當前num爲',num)
lock.release() # 釋放鎖,開啓下一個線程
for i in range(100):
t1=threading.Thread(target=myprint,args=[i+1,])
t1.start()
全局解釋器鎖(GIL):不管系統CPU核心數量多少,都保證python程序中同一時間點只能執行一個線程,對多CPU的系統來說造成資源的浪費(python的缺點),解決方法爲多進程
import time
from multiprocessing import Process #多進程包
#多進程可以實現多個任務並行,適用於多CPU
start=time.time()
def run(name):
# print(name,'執行')
time.sleep(5)
end=time.time()
print(name,'執行',end-start)
if __name__ == '__main__':
#注意多進程必須window系統,必須放在’if __name__ == '__main__':‘語句中
t1=Process(target=run,args=['t1',])
t2 = Process(target=run, args=['t2', ])
t3 = Process(target=run, args=['t3', ])
t1.start()
t2.start()
t3.start()