Python基礎知識(程式、程序與執行緒)
一、程式
1)程式:是指令和資料的集合,其本身沒有任何執行的含義,是一個靜態的概念。程序中的文字區域就是程式碼區,也就是程式。
2)Python標準庫中提供兩個模組,_thread和threading,_thread是低階模組,threading是高階模組,是對_thread進行了封裝,絕大多數情況下,我們只需要使用threading這個高階模組。啟動一個執行緒就是把一個函式傳入並建立Thread例項,然後呼叫start()開始執行。
import threading def run(): print("任務開始!") # 建立程序,程式本身就是一個執行緒,叫做主執行緒 t1 = threading.Thread(target=run) # 建立子執行緒 # 啟動執行緒 run() # 啟動主執行緒 t1.start() # 啟動子執行緒 >>任務開始! >>任務開始!
二、程序
1)程序:就是一段程式的執行過程,是一個動態的概念。它是一個具有一定獨立功能的程式關於某個資料集合的一次執行活動。它是作業系統動態執行的基本單元,在傳統的作業系統中,程序既是基本的分配單元,也是基本的執行單元。
2)程序的概念主要有兩點:第一,程序是一個實體,每一個程序都有它自己的地址空間,一般包括文字區域(text region)、資料區域(data region)和堆疊(stack region)。文字區域儲存處理器執行的程式碼;資料區域儲存變數和程序執行期間使用的動態分佈的記憶體;堆疊區域儲存活動過程呼叫的指令和本地變數。第二,程序是一個執行中的程式,程式是一個沒有生命的實體,只有處理器賦予程式生命時,它才能成為一個活動的實體,我們稱之為程序。
3)程序有三個狀態(就緒、執行和阻塞):就緒態,其實就是獲取cpu外的所有資源,只要處理器分配資源就可以馬上執行;執行態,獲得了處理器分配的資源,程式開始執行;阻塞態,當程式條件不夠時,需要等待條件滿足時才能執行,如等待I/O操作時候,此刻的狀態就叫阻塞態。
4)單程序/多程序執行案例
# 運用多程序操作模式,可以實現多個任務同時並行操作。 # 建立多程序 from multiprocessing import Process import time def run(name): print(name,"程序執行了!") time.sleep(2) if __name__ == "__main__": # 建立程序 p1 = Process(target=run,args=("p1",)) p2 = Process(target=run, args=("p2",)) p3 = Process(target=run, args=("p3",)) # 啟動程序 p1.start() p2.start() p3.start() >>p1 程序執行了! # 多個任務同時執行 >>p2 程序執行了! >>p3 程序執行了!
三、執行緒
1)執行緒:通常一個程序中可以包含多個執行緒,當然一個程序中至少有一個執行緒,不然沒有存在的意義。執行緒可以利用程序所擁有的資源,我們把程序作為分配資源的基本單位,而把執行緒作為獨立執行和獨立排程的基本單位。(若把程序比作一列火車,執行緒類似於火車車廂,單執行緒就像一個車廂)。
2)多執行緒:多執行緒是為了同步完成多項任務,不是為了提高執行效率,而是為了提供資源使用效率來提高系統的效率。(多執行緒就像火車的多個車廂)
3)單執行緒與多執行緒區別:剛開始直板洛基亞手機是單執行緒操作的,想聽音樂和發簡訊兩件事,只能按照先後順序一種一種的來操作;現在的智慧手機是多執行緒操作模式的,我們可以同時聽音樂、發簡訊及同時做其他的事情。
4)單執行緒/多執行緒執行案例
# 單執行緒 import threading import time def run(n): print("任務開始!", n) time.sleep(5) # 建立程序 t1 = threading.Thread(target=run, args=("t1",)) t1.start() >>任務開始! t1 >>[finished in 5s] # 單執行緒走完使用了5s
# 多程序 import threading import time def run(n): print("任務開始!", n) time.sleep(5) # 建立程序 # 程式本身就是一個執行緒,叫做主執行緒,手動建立的執行緒叫子執行緒。 t1 = threading.Thread(target=run, args=("t1",)) t2 = threading.Thread(target=run, args=("t2",)) # 啟動程序 t1.start() # 通常主執行緒的執行中不會等待子執行緒執行完畢,就會直接執行後面的程式碼 t2.start() t1.join() # 等待子執行緒執行完畢之後再執行主執行緒內容。 t2.join() print("執行完畢!") >>任務開始! t1 >>任務開始! t2 >>執行完畢! >>[finished in 5.1s] # 多執行緒走完只用了5.1s,若分別使用單執行緒的話需要10s。
5)執行緒鎖(互斥鎖)
# 執行緒鎖(全域性直譯器鎖GIL):不管電腦系統cpu核心數量是多少,保證Python程式中,同一時間只能執行一個執行緒。 import threading lock = threading.Lock() # 建立一個執行緒鎖(互斥鎖) num = 5 def run(name): lock.acquire() # 設定執行緒鎖 global num # 設定num為全域性變數 num = num - 1 print(f"執行緒{num}執行了!") lock.release() # 釋放執行緒鎖 # 建立程序,設定5個子執行緒 for i in range(5): t = threading.Thread(target=run,args=(i+1,)) # 建立子執行緒 # 啟動執行緒 t.start() # 啟動子執行緒 >>執行緒4執行了! >>執行緒3執行了! >>執行緒2執行了! >>執行緒1執行了! >>執行緒0執行了!
四、程序和執行緒的區別
1)程序和執行緒的主要差別在於它們是不同的作業系統資源管理方式。程序有獨立的地址空間,一個程序崩潰後,在保護模式下不會對其他程序產生影響。執行緒只是一個程序中的不同執行路徑,執行緒有自己的堆疊和區域性變數,但是執行緒之間沒有單獨的地址空間,一個執行緒死掉就等於整個程序也同時死掉。所以多程序的程式要比多執行緒的程式健壯,但是程序切換時,耗費資源較大,效率要差一些。對於一些要求同時進行並且又要共享某些變數的併發操作,只能用執行緒不能用程序。
2)簡而言之,一個程式執行至少有一個程序,一個程序至少有一個執行緒;執行緒的尺度小於程序,使得多執行緒的程式併發性高;程序在執行過程中擁有獨立的記憶體單元,而多執行緒共享記憶體,電腦中的RAM(簡稱運存),從而極大的提高了程式的執行效率。
3)一臺單核電腦同一時間只能處理一個程序中的一個執行緒,但可實現多執行緒不停切換。一臺8核電腦同一時間可同時處理8個執行緒。