Python中的多线程
在Python中,我们可以使用threading
模块来实现多线程。下面我们先来看一个简单的例子,看看如何创建和启动线程。
简单的多线程例子
import threading
import time
def worker(name):
print(f'线程 {name} 开始工作')
time.sleep(2)
print(f'线程 {name} 工作结束')
# 创建两个线程
thread1 = threading.Thread(target=worker, args=('A',))
thread2 = threading.Thread(target=worker, args=('B',))
# 启动线程
thread1.start()
thread2.start()
# 等待所有线程完成
thread1.join()
thread2.join()
print('所有线程完成')
在这个例子中,我们创建了两个线程,每个线程都执行worker
函数,并传入不同的参数。start()
方法启动线程,join()
方法等待线程完成。
多线程最佳实践
理解了基本概念后,我们再来看看一些多线程的最佳实践,确保你的多线程代码高效且不会出问题。
1. 使用锁保护共享数据
多个线程访问共享数据时,可能会导致数据不一致。我们可以使用Lock
来确保同一时间只有一个线程能访问共享数据。
import threading
counter = 0
lock = threading.Lock()
def increment():
global counter
for _ in range(100000):
with lock:
counter += 1
threads = []
for _ in range(5):
thread = threading.Thread(target=increment)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print(f'最终计数值: {counter}')
在这个例子中,我们用lock
来保护对counter
的访问,确保每次只有一个线程能修改它。
2. 使用线程池提高效率
手动管理线程可能会很麻烦,特别是当你需要创建很多线程时。Python提供了concurrent.futures
模块,可以方便地使用线程池来管理多个线程。
from concurrent.futures import ThreadPoolExecutor
import time
def worker(name):
print(f'线程 {name} 开始工作')
time.sleep(2)
print(f'线程 {name} 工作结束')
with ThreadPoolExecutor(max_workers=3) as executor:
names = ['A', 'B', 'C', 'D', 'E']
executor.map(worker, names)
print('所有线程完成')
在这个例子中,我们使用线程池来管理5个线程,并限制同时运行的线程数为3。
3. 避免全局变量
尽量避免在多线程程序中使用全局变量,因为全局变量会导致线程之间的数据共享和竞争。如果需要共享数据,尽量使用线程安全的队列或者其他同步机制。
import threading
import queue
def worker(q):
while not q.empty():
item = q.get()
print(f'处理项目: {item}')
q.task_done()
q = queue.Queue()
for item in range(10):
q.put(item)
threads = []
for _ in range(3):
thread = threading.Thread(target=worker, args=(q,))
threads.append(thread)
thread.start()
q.join()
for thread in threads:
thread.join()
print('所有项目处理完毕')
在这个例子中,我们使用queue.Queue
来管理任务队列,避免了全局变量的使用。