# Python的多線程和多進程 ## 一、簡介 併發是今天電腦編程中的一項重要能力,尤其是在面對需要大量計算或I/O操作的任務時。Python 提供了多種併發的處理方式,本篇文章將深入探討其中的兩種:多線程與多進程,解析其使用場景、優點、缺點,並結合代碼例子深入解讀。 ## 二、多線程 Pyth ...
Python的多線程和多進程
一、簡介
併發是今天電腦編程中的一項重要能力,尤其是在面對需要大量計算或I/O操作的任務時。Python 提供了多種併發的處理方式,本篇文章將深入探討其中的兩種:多線程與多進程,解析其使用場景、優點、缺點,並結合代碼例子深入解讀。
二、多線程
Python中的線程是利用threading
模塊實現的。線程是在同一個進程中運行的不同任務。
2.1 線程的基本使用
在Python中創建和啟動線程很簡單。下麵是一個簡單的例子:
import threading
import time
def print_numbers():
for i in range(10):
time.sleep(1)
print(i)
def print_letters():
for letter in 'abcdefghij':
time.sleep(1.5)
print(letter)
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)
thread1.start()
thread2.start()
在這個例子中,print_numbers
和print_letters
函數都在各自的線程中執行,彼此互不幹擾。
2.2 線程同步
由於線程共用記憶體,因此線程間的數據是可以互相訪問的。但是,當多個線程同時修改數據時就會出現問題。為瞭解決這個問題,我們需要使用線程同步工具,如鎖(Lock)和條件(Condition)等。
import threading
class BankAccount:
def __init__(self):
self.balance = 100 # 共用數據
self.lock = threading.Lock()
def deposit(self, amount):
with self.lock: # 使用鎖進行線程同步
balance = self.balance
balance += amount
self.balance = balance
def withdraw(self, amount):
with self.lock: # 使用鎖進行線程同步
balance = self.balance
balance -= amount
self.balance = balance
account = BankAccount()
特別說明:Python的線程雖然受到全局解釋器鎖(GIL)的限制,但是對於IO密集型任務(如網路IO或者磁碟IO),使用多線程可以顯著提高程式的執行效率。
三、多進程
Python中的進程是通過multiprocessing
模塊實現的。進程是操作系統中的一個執行實體,每個進程都有自己的記憶體空間,彼此互不影響。
3.1 進程的基本使用
在Python中創建和啟動進程也是非常簡單的:
from multiprocessing import Process
import os
def greet(name):
print(f'Hello {name}, I am process {os.getpid()}')
if __name__ == '__main__':
process = Process(target=greet, args=('Bob',))
process.start()
process.join()
3.2 進程間的通信
由於進程不共用記憶體,因此進程間通信(IPC)需要使用特定的機制,如管道(Pipe)、隊列(Queue)等。
from multiprocessing import Process, Queue
def worker(q):
q.put('Hello from
process')
if __name__ == '__main__':
q = Queue()
process = Process(target=worker, args=(q,))
process.start()
process.join()
print(q.get()) # Prints: Hello from process
特別說明:Python的多進程對於計算密集型任務是一個很好的選擇,因為每個進程都有自己的Python解釋器和記憶體空間,可以並行計算。
One More Thing
讓我們再深入地看一下concurrent.futures
模塊,這是一個在Python中同時處理多線程和多進程的更高級的工具。concurrent.futures
模
塊提供了一個高級的介面,將非同步執行的任務放入到線程或者進程的池中,然後通過future對象來獲取執行結果。這個模塊使得處理線程和進程變得更簡單。
下麵是一個例子:
from concurrent.futures import ThreadPoolExecutor, as_completed
def worker(x):
return x * x
with ThreadPoolExecutor(max_workers=4) as executor:
futures = {executor.submit(worker, x) for x in range(10)}
for future in as_completed(futures):
print(future.result())
這個代碼創建了一個線程池,並且向線程池提交了10個任務。然後,通過future對象獲取每個任務的結果。這裡的as_completed
函數提供了一種處理完成的future的方式。
通過這種方式,你可以輕鬆地切換線程和進程,只需要將ThreadPoolExecutor
更改為ProcessPoolExecutor
。
無論你是處理IO密集型任務還是計算密集型任務,Python的多線程和多進程都提供了很好的解決方案。理解它們的運行機制和適用場景,可以幫助你更好地設計和優化你的程式。
如有幫助,請多關註
個人微信公眾號:【Python全視角】
TeahLead_KrisChang,10+年的互聯網和人工智慧從業經驗,10年+技術和業務團隊管理經驗,同濟軟體工程本科,復旦工程管理碩士,阿裡雲認證雲服務資深架構師,上億營收AI產品業務負責人。