在現代計算機應用和編程中,充分利用多核處理能力是提高計算性能和效率的重要手段之一。而編程中最常見的並行編程方式之一就是多線程編程,它能夠在一個單獨的程序中同時執行多個任務,從而提高整個應用程序的執行效率。Python作為一款主流編程語言,其也提供了多線程編程的相關支持。本文將基於這一主題,針對Python多線程編程技術的相關內容進行詳細闡述。
一、Python多線程怎麼寫
Python多線程編程即在一個程序中創建多個執行線程,其中主線程繼續運行,而子線程則通過調用一定的函數並完成相應的任務。Python標準庫中提供了Thread類,是一個默認的線程類,可以通過多個實例來創建相應的線程;常用的還有Thread類的派生類——即Thread子類,這個類可以通過重寫Thread類的run方法來完成相應的處理。下面是一個簡單的Python多線程編程示例,通過繼承Thread類、重寫run方法,並綁定相應的參數,完成對不同函數調用的多線程執行:
import threading class MyThread(threading.Thread): def __init__(self, func, args): super(MyThread, self).__init__() self.func = func self.args = args def run(self): self.result = self.func(*self.args) def get_result(self): try: return self.result except Exception: return None def add(x, y): return x+y def subtract(x, y): return x-y def multiply(x, y): return x*y def divide(x, y): return x/y if __name__=="__main__": threads = [] lists = [(1, 2), (5, 4), (2, 5), (2, 2)] for item in lists: t1 = MyThread(add, item) t2 = MyThread(subtract, item) t3 = MyThread(multiply, item) t4 = MyThread(divide, item) threads.append(t1) threads.append(t2) threads.append(t3) threads.append(t4) for t in threads: t.start() for t in threads: t.join() print(t.get_result())
在該示例中,我們繼承了Python標準庫中的Thread類,並通過構造函數和run方法來完成線程的對應功能。通過控制線程的調度,可以實現多個線程的並行執行,從而提高整個程序的性能。
二、Python多線程調用同一個函數
在Python多線程編程中,有時我們需要對同一個函數進行並行調用,從而加快相應的計算速度。Python提供了針對同一個函數並行調用的方法,其中最常見的是使用ThreadPoolExecutor類,它通過非同步、可調用和飽和策略等特點實現了多線程執行。下面是針對Python多線程調用同一個函數的一個簡單示例:
from concurrent.futures import ThreadPoolExecutor def my_func(x, y): return x+y if __name__=="__main__": with ThreadPoolExecutor(max_workers=2) as executor: future1 = executor.submit(my_func, 1, 2) future2 = executor.submit(my_func, 3, 4) print(future1.result()) print(future2.result())
在該示例中,我們定義了一個名為my_func的函數,並指定了相應的參數;並且利用Python的ThreadPoolExecutor類對該函數進行了非同步並行調用,最終得到相應的結果。
三、Python多線程並行
在Python多線程編程中,最大的好處之一就是能夠並行處理,即進行多個任務的同時處理。並行能夠提高程序的執行效率,縮短程序的運行時間。下面是Python多線程並行的一個簡單示例:
import time import threading def func(): print('Begin Func') time.sleep(5) print('End Func') def main(): threads = [] for i in range(5): t = threading.Thread(target=func) threads.append(t) t.start() for t in threads: t.join() if __name__ == '__main__': main()
在該示例中,我們通過Python多線程並行方式實現了對func()函數的多次調用。通過控制不同線程的調度來實現並行處理,從而提高整個程序的效率。
四、Python多線程多進程
Python多線程和多進程的區別在於前者主要是在同一個進程內執行,而後者則是不同的進程之間執行。根據任務的不同,我們可以選擇多進程或者多線程。下面是Python多線程和多進程之間的簡單對比:
1、Python多進程編程適用於計算密集型任務,即需要大量CPU計算的任務,因為在多進程編程中,Python將會為主進程和子進程分配不同的CPU時間和資源,從而加快相應任務的執行。
2、Python多線程編程適用於I/O密集型任務,即需要讀取或者寫入數據的任務。因為I/O密集型任務主要是在等待外部處理,Python多線程編程可以通過進一步並行處理來提高相應任務的效率。
因此,在Python編程中,我們需要根據不同的任務需求來選擇多進程或者多線程編程方式。
五、Python多線程停止控制
在Python多線程編程中,我們需要能夠對不同的線程進行停止控制,從而控制整個程序的運行。Python提供了多種停止線程的方式,具體如下:
1、使用自定義標誌或者異常:在多線程編程中,我們可以使用自定義標誌或者異常來停止特定的線程。這個方法比較簡單,但是需要線程在特定的時間掛起,從而完成停止。
2、使用Thread.alive()函數:在Python多線程編程中,我們也可以利用Thread.alive()函數判斷線程是否處於活動狀態,進而完成線程的停止控制。
3、使用Event對象:Python提供了Event對象,通過wait和set函數可以實現線程的條件同步,進而實現線程的停止控制。
六、Python多線程下載
在Python多線程編程中,我們經常需要對不同的資源進行下載。Python提供了相應的並行加下載的方式來加快下載的效率,具體如下:
1、使用urlib庫實現並行下載:urllib是Python的標準庫之一,可以通過其urlretrieve函數來下載文件。並行下載可以通過Python多線程編程實現。下面是一個示例:
import urllib.request import time import threading import os,sys def file_get(url): try: filename = os.path.basename(url) data = urllib.request.urlopen(url,timeout=5) f = open('E:\\DownloadFiles\\'+filename,'wb') f.write(data.read()) f.close() except Exception as e: print(e) class MyThread(threading.Thread): def __init__(self, func, args, name=''): threading.Thread.__init__(self) self.name = name self.func = func self.args = args def getResult(self): return self.res def run(self): self.res = self.func(*self.args) if __name__=='__main__': urls = ["http://www.jyw.cn/2021/njffmm_0409/31.jpg", "http://pic.pimg.tw/asia-english/1363724244-916205393.jpg", "http://pic.pimg.tw/asia-english/1363724244-916205393.jpg"] for url in urls: t = MyThread(file_get,(url,)) t.start()
2、使用ThreadPoolExecutor類實現多線程下載:下面是相對應的示例:
import concurrent.futures import urllib.request img_urls = [ 'http://blog.hexu.pro/images/avatar-default.png', # ... ] def download_img(img_url): img_filename = img_url.split('/')[-1] + ".jpg" urllib.request.urlretrieve(img_url, img_filename) return f'({img_song}: {img_filename})' with concurrent.futures.ThreadPoolExecutor() as executor: results = executor.map(download_img, img_urls) for result in results: print(result)
七、Python多線程運行原理
Python多線程運行原理與其他編程語言中多線程運行原理類似,都是採用多進程編程方式,即在一個主進程下開闢多個子線程並行執行不同的任務,進而提高程序的執行效率。與其他語言不同的是,Python中存在GIL全局解釋器鎖的問題,即同一時刻同一進程中只會有一個線程處於運行狀態,其他線程處於掛起狀態,無法繼續執行。為了解決這個問題,Python引入了多進程編程方式,即在不同進程之間進行並行計算。
八、Python多線程實例
下面是一個針對Python多線程編程實例的示例——簡單的針對正方形和圓形的區域計算程序。具體代碼如下:
from threading import Thread, Lock import time mutex = Lock() class SquareArea: def __init__(self): self.total = 0 def add_square_area(self, start, end): mutex.acquire() for i in range(start, end): self.total += i * i mutex.release() class CircleArea: def __init__(self): self.total = 0 def add_circle_area(self, start, end): mutex.acquire() for i in range(start, end): self.total += i * i * 3.14 mutex.release() if __name__ == '__main__': square_area = SquareArea() circle_area = CircleArea() t1 = Thread(target=square_area.add_square_area, args=(0, 1000000)) t2 = Thread(target=circle_area.add_circle_area, args=(0, 1000000)) t1.start() t2.start() t1.join() t2.join() print(square_area.total) print(circle_area.total)
在該示例中,我們定義了一個計算正方形面積和圓形面積的多線程程序,採用互斥鎖的方式來實現線程的同步控制,從而避免了多線程編程的常見問題,同時可以達到較好的程序效率和性能。
九、Python多線程和多進程的區別
Python多線程和多進程區別在於,前者主要是在同一個進程內執行多個線程,而後者則是在不同的進程之間執行。具體而言,Python多線程和多進程的區別有以下幾個方面:
1、Python多線程的好處主要體現在能夠提高I/O操作等任務完成的效率,而多進程的優勢則在於其能夠充分發揮計算機CPU的效率,從而加快演算法的執行。
2、Python多線程的缺點主要在於存在GIL全局解釋器鎖的問題,這個問題會導致多線程無法充分發揮多核CPU的效率,從而降低程序的性能,而多進程則不存在這個問題。</p
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/304888.html