1. 程式人生 > 實用技巧 >python3 多執行緒

python3 多執行緒

多執行緒的優點:①使用執行緒可以吧佔據長時間的程式中的任務放到後臺去處理

②用於介面可以更加吸引人,比如使用者點選了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度

③程式的執行速度可能加快

④在一些等待的任務實現上如使用者輸入、檔案讀寫和網路收發資料等,執行緒就發揮作用了。在這種情況下我們可以釋放一些珍貴的資源如記憶體佔用等等。

每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒進行控制。

每個執行緒都有他自己的一組暫存器稱為執行緒的上下文,該上下文反映了執行緒上次執行該執行緒的CPU暫存器的狀態。

指令指標和堆疊指標暫存器是執行緒上下文中兩個最重要的暫存器,執行緒總是在程序得到上下文中執行的,這些地址都用於標誌擁有執行緒的程序地址空間中的記憶體。

注意:①執行緒可以被搶佔(中斷)

②在其他執行緒正在執行時,執行緒可以暫時擱置(也稱為睡眠)---這就是執行緒的退讓

執行緒可以分為:①核心執行緒:由作業系統核心 建立和撤銷

②使用者執行緒:不需要核心支援而在使用者程式中實現的執行緒

Python3多執行緒中常用的兩個模組未:①_thread ② threading(推薦使用)

其中,thread模組已經被廢棄,使用者可以使用threading替代,所以在Python3中不能再使用 thread模組。為了相容性,Python3將 thread重新命名為 _thread。

threading模組除了包含_thread模組中的所有方法外,還提供了額外的方法:

①threading.currentThread(): 返回當前的執行緒變數

②threading.enumerate():返回一個包含正在執行的執行緒的list。正在執行指執行緒啟動後、結束前,不包括啟動前和終止後的執行緒。

③threading.activeCount(): 返回正在執行的執行緒數量,與len(threading.enumerate()有相同的效果。

除了使用方法外,執行緒模組提供了thread類來處理執行緒,thread類提供瞭如下方法:

①run():用以表示執行緒活動的方法

②start(): 啟動執行緒活動

③join([time]): 等待至執行緒中止。阻塞執行緒直至執行緒的join()方法被呼叫中止-正常 退出或者丟擲未處理的異常-或者是可選的超時發生

④isAlive(): 返回執行緒是否活動

⑤getName(): 返回執行緒名

⑥setName(): 設定執行緒名

一個無執行緒程式:

import timestart = time.time()
people = 500      # 假設有500個人
def action(num):
    global people
    while people>0:
        people -= 50     # 每次運輸50人
        print("車輛編號:%d, 當前車站人數:%d" %(num, people))
        time.sleep(1)
        
num = 1     # 車輛編號
action(num)
end = time.time()
print("Duration time: %0.3f" %(end-start))

  結果:

車輛編號:1, 當前車站人數:450
車輛編號:1, 當前車站人數:400
車輛編號:1, 當前車站人數:350
車輛編號:1, 當前車站人數:300
車輛編號:1, 當前車站人數:250
車輛編號:1, 當前車站人數:200
車輛編號:1, 當前車站人數:150
車輛編號:1, 當前車站人數:100
車輛編號:1, 當前車站人數:50
車輛編號:1, 當前車站人數:0
Duration time: 10.001

  

一個單執行緒程式:

import threading
import timestart = time.time()
people = 500      # 假設有500個人
def action(num):
    global people
    while people>0:
        people -= 50     # 每次運輸50人
        print("車輛編號:%d, 當前車站人數:%d" %(num, people))
        time.sleep(1)

num = 1     # 車輛編號
vehicle = threading.Thread(target=action, args=(num,))  # 新建車輛
vehicle.start()     # 啟動車輛
vehicle.join()      # 檢查到站車輛

end = time.time()
print("Duration time: %0.3f" %(end-start))

  結果:

車輛編號:1, 當前車站人數:450
車輛編號:1, 當前車站人數:400
車輛編號:1, 當前車站人數:350
車輛編號:1, 當前車站人數:300
車輛編號:1, 當前車站人數:250
車輛編號:1, 當前車站人數:200
車輛編號:1, 當前車站人數:150
車輛編號:1, 當前車站人數:100
車輛編號:1, 當前車站人數:50
車輛編號:1, 當前車站人數:0
Duration time: 10.001

  

一個多執行緒程式(傳遞物件方式建立執行緒):

# -*- coding: utf-8 -*
import threading
import time

people = 500      # 假設有500個人
def action(num):
    global people
    while people>0:
        people -= 50     # 每次運輸50人
        print("車輛編號:%d, 當前車站人數:%d" %(num, people))
        time.sleep(1)

start = time.time()
vehicles = []       # 新建車輛組
for num in range(5):
    vehicle = threading.Thread(target=action, args=(num,)) # 新建車輛
    vehicles.append(vehicle)     # 新增車輛到車輛組中

for vehicle in vehicles:
    vehicle.start()  # 分別啟動車輛

for vehicle in vehicles:
    vehicle.join()      # 分別檢查到站車輛
end = time.time()
print("Duration time: %0.3f" % (end-start))

  執行結果:

車輛編號:0, 當前車站人數:450
車輛編號:1, 當前車站人數:400
車輛編號:2, 當前車站人數:350
車輛編號:3, 當前車站人數:300
車輛編號:4, 當前車站人數:250
車輛編號:2, 當前車站人數:200
車輛編號:1, 當前車站人數:150
車輛編號:0, 當前車站人數:100
車輛編號:3, 當前車站人數:50
車輛編號:4, 當前車站人數:0
Duration time: 2.001

  一個多執行緒程式(覆蓋子類的方式):

# -*- coding: utf-8 -*
import threading
import time

people = 500
class MyThread(threading.Thread):
    def __init__(self, num):
        super(MyThread, self).__init__()
        self.num = num

    def run(self):
        global people
        while people > 0:
            people -= 50
            print("車輛編號:%d, 當前車站人數:%d " % (self.num, people))
            time.sleep(1)

start = time.time()
vehicles = []       # 新建車輛組
for num in range(5):        # 設定車輛數
    vehicle = MyThread(num)     # 新建車輛
    vehicles.append(vehicle)     # 新增車輛到車輛組中
    vehicle.start()     #啟動車輛

for vehicle in vehicles:
    vehicle.join()      # 分別檢查到站車輛
end = time.time()
print("Duration time: %0.3f" % (end-start))

  

結果:

車輛編號:0, 當前車站人數:450
車輛編號:1, 當前車站人數:400
車輛編號:2, 當前車站人數:350
車輛編號:3, 當前車站人數:300
車輛編號:4, 當前車站人數:250
車輛編號:0, 當前車站人數:200
車輛編號:2, 當前車站人數:150 車輛編號:3, 當前車站人數:100車輛編號:1, 當前車站人數:50


車輛編號:4, 當前車站人數:0
Duration time: 2.003

  結果分析: ①通過顯示結果可以發現,不使用執行緒的程式和使用單執行緒的程式執行時間是一樣的,這是因為我們正常執行一個指令碼,本質上就是單執行緒執行。

②建立多執行緒的兩種方法執行時間也是一樣的,因為最終都是交給thread類來處理,自行選擇即可。

③多執行緒執行時間明顯比單線快大概5倍,從理論上來說是和執行緒數成正比的,但是實際應用中並非執行緒越多就越好,因為執行緒越多消耗的資源也就越多。

注意:①建立執行緒物件後,必須通過呼叫執行緒的start()方法啟動其活動,這將在單獨的控制執行緒中呼叫run()方法

②一旦執行緒的活動開始,執行緒就是被認為是“活著的”,當run()方法終止時,它會停止活動,或者引發異常

③執行緒可以呼叫is_alive()方法測試是否處於活動狀態,其他執行緒可以呼叫執行緒的join()方法,這將阻塞呼叫執行緒,直到呼叫其join()方法的執行緒終止

④執行緒有一個名稱,這個名稱可以傳遞給建構函式,並通過name屬性讀取或更改

⑤執行緒可以標記為“守護程式執行緒”,這個標誌的意義在於,當只剩下守護程序執行緒時,整個Python程式都會推出,可以通過守護程式屬性設定該標誌

更多請看: https://www.cnblogs.com/leozhanggg/p/10335098.html