1. 基础概念
1.1 进程与线程
- 进程: 系统资源分配和调度的基本单位
- 线程: CPU调度的最小单位,是进程的执行实体
- 关系:
- 一个进程可以包含多个线程
- 线程共享进程的资源
- 线程拥有自己的栈空间和寄存器
1.2 Python线程特点
- 主线程是进程的第一个线程
- 使用threading模块创建和管理线程
- 受GIL(全局解释器锁)影响
2. 线程创建和管理
2.1 使用Thread类创建线程
from threading import Thread
# 方法1:传入目标函数
def task():
print("Thread task")
thread = Thread(target=task)
thread.start()
# 方法2:传入带参数的函数
def task_with_args(name):
print(f"Thread {name}")
thread = Thread(target=task_with_args, args=("Thread-1",))
thread.start()
2.2 继承Thread类创建线程
class MyThread(Thread):
def __init__(self, name=None):
super().__init__()
self.name = name
def run(self):
print(f"Thread {self.name} is running")
thread = MyThread("Custom-Thread")
thread.start()
2.3 线程管理方法
# 获取当前线程
current = threading.current_thread()
# 获取线程名
name = thread.getName()
# 设置线程名
thread.setName("New-Name")
# 获取活动线程数
count = threading.active_count()
# 获取所有活动线程
threads = threading.enumerate()
# 等待线程结束
thread.join()
3. 线程同步机制
3.1 互斥锁(Lock)
from threading import Lock
# 创建锁
mutex = Lock()
def safe_task():
# 获取锁
mutex.acquire()
try:
# 临界区代码
pass
finally:
# 释放锁
mutex.release()
# 使用with语句(推荐)
def safe_task_with():
with mutex:
# 临界区代码
pass
3.2 线程安全队列(Queue)
from queue import Queue
# 创建线程安全队列
q = Queue(maxsize=10)
# 生产者
def producer():
while True:
item = produce_item()
q.put(item)
# 消费者
def consumer():
while True:
item = q.get()
process_item(item)
q.task_done()
4. 线程数据隔离
4.1 使用threading.local()
import threading
# 创建线程本地存储
local_data = threading.local()
def worker():
# 每个线程都有独立的存储空间
local_data.x = 0
# 修改本地数据不会影响其他线程
local_data.x += 1
5. 线程同步模式
5.1 生产者-消费者模式
from threading import Thread, Event
from queue import Queue
class Producer(Thread):
def __init__(self, queue):
super().__init__()
self.queue = queue
def run(self):
while True:
item = self.produce_item()
self.queue.put(item)
class Consumer(Thread):
def __init__(self, queue):
super().__init__()
self.queue = queue
def run(self):
while True:
item = self.queue.get()
self.process_item(item)
self.queue.task_done()
6. 注意事项和最佳实践
6.1 GIL的影响
- Python的GIL限制了多线程在CPU密集型任务上的性能
- IO密集型任务仍然可以从多线程中受益
- 考虑使用多进程来绕过GIL限制
6.2 死锁预防
- 避免循环等待
- 使用超时机制
- 按固定顺序获取锁
- 使用with语句自动释放锁
6.3 性能优化
- 合理设置线程数量
- 避免过多的线程同步操作
- 使用线程池管理线程
- 考虑使用异步IO替代多线程
6.4 调试技巧
- 使用logging模块记录线程活动
- 设置线程名便于调试
- 使用threading.current_thread()确定当前线程
- 使用threading.enumerate()监控活动线程
7. 示例应用
7.1 并发下载器
import threading
import requests
from queue import Queue
class DownloadWorker(Thread):
def __init__(self, queue):
super().__init__()
self.queue = queue
def run(self):
while True:
url = self.queue.get()
try:
self.download_file(url)
finally:
self.queue.task_done()
def download_file(self, url):
response = requests.get(url)
# 处理下载内容
7.2 线程池实现
from concurrent.futures import ThreadPoolExecutor
def process_item(item):
# 处理单个任务
pass
# 创建线程池
with ThreadPoolExecutor(max_workers=4) as executor:
# 提交任务
future = executor.submit(process_item, item)
# 获取结果
result = future.result()