在現代計算機應用和編程中,充分利用多核處理能力是提高計算性能和效率的重要手段之一。而編程中最常見的並行編程方式之一就是多線程編程,它能夠在一個單獨的程序中同時執行多個任務,從而提高整個應用程序的執行效率。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-hk/n/304888.html
微信掃一掃
支付寶掃一掃