一、並發與多線程
在計算機領域中,我們會頻繁聽到並發和並行兩個概念。其中,並發是指同一時間段內處理多個任務,而並行則是指同一時刻執行多個任務。那麼多線程技術可以幫助實現並發操作。
在Python中,我們可以使用threading模塊來創建和操作線程對象。其中,threading模塊中最常用的是Thread類。下面是一個簡單的多線程的示例代碼:
import threading
def worker():
"""Thread worker function"""
print('Worker')
threads = []
for i in range(5):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
通過上面的代碼可以看出,我們創建了5個線程,這5個線程共享同一個函數worker()。每個線程都會執行worker()函數中的操作。這就實現了並發操作,提高了程序的效率。
二、Python的全局解釋器鎖(GIL)
但是,需要注意的是,Python解釋器中的全局解釋器鎖(GIL)會限制Python線程的並行執行,因為在同一時間只能有一個線程在解釋器中運行Python字節碼。這也就是說,Python多線程是並發執行的,而不是並行執行的。
了解了GIL的限制,我們可以考慮使用線程池來提高並發操作的效率。線程池中維護着大量線程,在需要的時候分配給程序使用,從而避免了線程創建和銷毀所帶來的開銷。下面是一個使用Python中的ThreadPoolExecutor實現線程池的示例代碼:
from concurrent.futures import ThreadPoolExecutor
import concurrent.futures
def worker(count):
"""Thread worker function"""
print(f'Thread-{count}')
with ThreadPoolExecutor(max_workers=5) as executor:
future_to_count = {executor.submit(worker, count): count for count in range(5)}
for future in concurrent.futures.as_completed(future_to_count):
count = future_to_count[future]
try:
data = future.result()
except Exception as exc:
print(f'Thread-{count} generated an exception: {exc}')
else:
print(f'Thread-{count} done')
上面的代碼中,我們使用ThreadPoolExecutor創建了一個最大5個線程的線程池,接着使用submit方法向線程池中提交任務,最後通過as_completed()函數獲得每個線程的結果。這種方式可以大大提高並發操作的效率。
三、使用Python多線程進行IO密集型操作
除了使用線程池來提高並發操作的效率外,我們還可以使用多線程解決一些IO密集型操作。因為在這種情況下,線程的執行不會阻塞CPU,而是在等待IO操作完成時被阻塞,這就可以讓其他線程繼續執行,並提高效率。
下面是一個使用多線程處理IO密集型操作的示例代碼:
import threading
import requests
def download(url):
"""Thread worker function"""
filename = url.split('/')[-1]
with open(filename, 'wb') as f:
response = requests.get(url)
f.write(response.content)
print(f'Downloaded {filename}')
urls = [
'https://picsum.photos/200/300',
'https://picsum.photos/250/350',
'https://picsum.photos/300/400',
'https://picsum.photos/350/450',
'https://picsum.photos/400/500'
]
threads = []
for url in urls:
t = threading.Thread(target=download, args=(url,))
threads.append(t)
t.start()
上面的代碼中,我們使用requests庫下載了一些圖片,並使用多線程的方式下載,加快了下載的速度。
四、使用Python多線程進行CPU密集型操作
在Python中,並發編程主要是通過多線程完成的,但是多線程對於CPU密集型操作並不友好。因為在同一時間只有一個線程可以在解釋器中運行Python字節碼,所以線程的數量也不會對程序的性能起到很大的作用。
在這種情況下,我們可以考慮使用多進程來實現並發操作。每個進程都維護着自己的解釋器和GIL,因此可以實現真正的並行操作。下面是一個使用Python多進程進行CPU密集型操作的示例代碼:
import multiprocessing
def fib(n):
"""Fibonacci function"""
if n<=2:
return 1
return fib(n-1) + fib(n-2)
pool = multiprocessing.Pool(processes=4)
inputs = [10, 11, 12, 13]
outputs = pool.map(fib, inputs)
print(outputs)
上面的代碼中,我們使用Python的multiprocessing.Pool類實現多進程計算斐波那契數列。在這種情況下,每個進程維護着自己的解釋器和GIL,因此可以實現並行操作。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/305007.html