Python 的 threading 模块是用于实现多线程编程的标准库之一。多线程允许程序在同一时间内执行多个任务,从而提高程序的效率和响应速度。
threading
threading 模块提供了创建和管理线程的工具,使得开发者可以轻松地编写并发程序。
什么是线程?
你可以把线程想象成办公室里的员工:
一个单线程程序就像只有一个员工,他必须顺序完成打印文档、回复邮件、泡咖啡等所有工作。
多线程程序则像拥有多个员工,他们可以同时进行不同的任务,大大提高了工作效率。
在计算机科学中:
为什么使用多线程?
在单线程程序中,任务是一个接一个地顺序执行的。如果某个任务需要等待(例如等待网络响应或文件读取),整个程序会被阻塞,直到该任务完成。而多线程可以让程序在等待某个任务的同时,继续执行其他任务,从而提高程序的整体性能。
Python 的线程与全局解释器锁 (GIL)
Python 有一个叫做 全局解释器锁 (Global Interpreter Lock, GIL) 的机制,GIL 确保了在任意时刻,只有一个线程可以执行 Python 字节码。
这意味着什么? 对于 CPU 密集型任务(如科学计算、图像处理),由于 GIL 的存在,多线程通常无法利用多核优势来提升计算速度,甚至可能因为线程切换的开销而变慢。
那么,Python 多线程的用武之地在哪里? 对于 I/O 密集型任务(如网络请求、读写文件、等待用户输入),线程在等待 I/O 操作完成时会释放 GIL,从而让其他线程运行。这可以显著提升程序的整体响应速度和效率,因为你在等待一个网页响应时,程序可以去处理另一个任务。
如何使用 threading 模块?
使用 threading 模块的第一步就是导入它:
import threading import time # 用于模拟耗时操作
创建线程最基本的方式是使用 threading.Thread 类。
threading.Thread
语法说明:
thread_obj = threading.Thread(target=函数名, args=(参数元组,))
(参数,)
1. 创建线程
在 Python 中,可以通过继承 threading.Thread 类或直接使用 threading.Thread 构造函数来创建线程。
方法 1:继承 threading.Thread 类
方法 2:使用 threading.Thread 构造函数
2. 线程同步
在多线程编程中,多个线程可能会同时访问共享资源,这可能导致数据不一致的问题。为了避免这种情况,可以使用线程同步机制,如锁(Lock)。
Lock
3. 线程间通信
线程间通信可以通过队列(Queue)来实现。Queue 是线程安全的,可以在多个线程之间安全地传递数据。
Queue
常用类、方法及属性
1. 核心类
t = Thread(target=func, args=(1,))
threading.Lock
lock = Lock()
threading.RLock
rlock = RLock()
threading.Event
event = Event()
threading.Condition
cond = Condition()
threading.Semaphore
sem = Semaphore(3)
threading.BoundedSemaphore
b_sem = BoundedSemaphore(2)
threading.Timer
timer = Timer(5.0, func)
threading.local
local_data = threading.local()
2. Thread 对象常用方法/属性
start()
t.start()
run()
join(timeout=None)
t.join()
is_alive()
if t.is_alive():
name
t.name = "Worker-1"
daemon
t.daemon = True
ident
None
print(t.ident)
3. Lock/RLock 常用方法
acquire(blocking=True, timeout=-1)
lock.acquire()
release()
lock.release()
locked()
if not lock.locked():
4. Event 常用方法
set()
event.set()
clear()
event.clear()
wait(timeout=None)
event.wait(2.0)
is_set()
if event.is_set():
5. Condition 常用方法
cond.wait()
notify(n=1)
n
cond.notify(2)
notify_all()
cond.notify_all()
6. 模块级函数/属性
threading.active_count()
print(threading.active_count())
threading.current_thread()
print(threading.current_thread().name)
threading.enumerate()
for t in threading.enumerate():
threading.main_thread()
if threading.current_thread() is threading.main_thread():
threading.get_ident()
print(threading.get_ident())
实例
1. 基础线程创建
2. 使用锁保护共享资源
3. 事件同步
4. 生产者-消费者模型(Condition)
注意事项
全局解释器锁(GIL):Python 的 GIL 会限制同一时间只有一个线程执行 Python 字节码。因此,在 CPU 密集型任务中,多线程可能不会带来性能提升。对于 I/O 密集型任务,多线程仍然是有益的。
线程安全:在多线程环境中,确保对共享资源的访问是线程安全的,避免数据竞争和死锁。
线程数量:创建过多的线程可能会导致系统资源耗尽,影响程序性能。合理控制线程数量,或使用线程池(ThreadPoolExecutor)来管理线程。
ThreadPoolExecutor