Python多线程
Python 的多线程可以通过 threading 模块实现,适用于 I/O 密集型任务(如文件操作、网络请求等)。然而,由于全局解释器锁(GIL)的存在,Python 多线程对 CPU 密集型任务的支持有限,无法充分利用多核 CPU。
以下是 Python 多线程的常见用法和示例:
1. 基本用法
使用 threading.Thread 类创建并启动线程。
示例:创建并启动线程
import threading
import time
def worker(name):
print(f"Thread {name} is starting...")
time.sleep(2)
print(f"Thread {name} is done.")
# 创建线程
thread1 = threading.Thread(target=worker, args=("A",))
thread2 = threading.Thread(target=worker, args=("B",))
# 启动线程
thread1.start()
thread2.start()
# 等待线程结束
thread1.join()
thread2.join()
print("All threads are complete.")
2. 使用 Thread 子类
可以通过继承 Thread 类来自定义线程。
示例:自定义线程类
import threading
import time
class MyThread(threading.Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print(f"Thread {self.name} is starting...")
time.sleep(2)
print(f"Thread {self.name} is done.")
# 创建并启动线程
thread1 = MyThread("A")
thread2 = MyThread("B")
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("All threads are complete.")
3. 使用线程锁(Lock)
当多个线程需要访问共享资源时,需要使用线程锁来避免竞争条件。
示例:线程锁
import threading
import time
counter = 0
lock = threading.Lock()
def worker():
global counter
for _ in range(100000):
with lock: # 确保只有一个线程可以修改 counter
counter += 1
# 创建多个线程
threads = [threading.Thread(target=worker) for _ in range(5)]
for t in threads:
t.start()
for t in threads:
t.join()
print(f"Final counter value: {counter}")
4. 使用 ThreadPoolExecutor
concurrent.futures.ThreadPoolExecutor 提供了更高级的线程池管理。
示例:线程池的 map
from concurrent.futures import ThreadPoolExecutor
import time
def task(n):
time.sleep(1)
return n * n
# 创建线程池
with ThreadPoolExecutor(max_workers=3) as executor:
results = executor.map(task, range(5))
print(list(results))
示例:线程池的异步任务
from concurrent.futures import ThreadPoolExecutor
def task(n):
return n * n
def callback(future):
print(f"Result: {future.result()}")
# 创建线程池
with ThreadPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(task, i) for i in range(5)]
for future in futures:
future.add_done_callback(callback)
5. 使用 Event 控制线程
threading.Event 是一种线程间通信机制,常用于线程同步。
示例:使用 Event
import threading
import time
event = threading.Event()
def worker():
print("Waiting for the event to be set...")
event.wait() # 等待事件被设置
print("Event is set, continuing work...")
thread = threading.Thread(target=worker)
thread.start()
time.sleep(2)
print("Setting the event...")
event.set() # 设置事件
thread.join()
6. 使用 Queue 在线程间传递数据
queue.Queue 是线程安全的队列,适用于线程间的数据传递。
示例:生产者-消费者模型
import threading
import queue
import time
q = queue.Queue()
def producer():
for i in range(5):
time.sleep(1)
q.put(i)
print(f"Produced: {i}")
def consumer():
while True:
item = q.get()
if item is None:
break
print(f"Consumed: {item}")
q.task_done()
# 创建线程
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)
producer_thread.start()
consumer_thread.start()
producer_thread.join()
q.put(None) # 结束信号
consumer_thread.join()
7. 常见注意事项
- 适用场景:多线程适用于 I/O 密集型任务(如文件读写、网络操作)。对于 CPU 密集型任务,推荐使用多进程(
multiprocessing)。 - 线程安全:当多个线程访问共享数据时,使用锁(
Lock)保护数据。 - GIL 限制:由于全局解释器锁(GIL),Python 的多线程不能完全利用多核 CPU,但 I/O 密集型任务受影响较小。