Python 多线程编程入门:创建、同步与队列通信
Python 多线程常用于处理网络请求、文件读写等 I/O 密集型任务。本文基于官方 recommended 的 threading 模块,系统讲解线程创建、锁机制同步以及 queue 队列通信的核心用法,帮助开发者快速构建安全可控的并发流程。
创建线程的标准方式
Python 中推荐直接使用 threading 模块。创建线程主要有两种模式:继承重写 run() 方法,或直接传入目标函数。后者代码更简洁,也是现代开发的首选。
import threading
import time
def worker(thread_name, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print(f"{thread_name}: {time.ctime(time.time())}")
# 直接传入函数作为 target(推荐)
t1 = threading.Thread(target=worker, args=("Thread-A", 2), name="Worker-A")
t2 = threading.Thread(target=worker, args=("Thread-B", 4), name="Worker-B")
# 启动线程
t1.start()
t2.start()
print("主线程已启动,正在等待子线程结束...")
t1.join()
t2.join()
print("所有任务执行完毕。")
若需自定义线程类并维护更多状态,可继承 threading.Thread。注意必须在 __init__ 中调用 super().__init__(),并将业务逻辑写在 run() 中,而非构造阶段。
实现线程同步与安全访问
当多个线程共同修改同一份数据结构时,极易引发竞态条件。Python 提供了 threading.Lock 来实现互斥同步。通过 acquire() 获取锁,release() 释放锁,可确保临界区代码在任意时刻仅被一个线程执行。
import threading
import time
shared_counter = 0
lock = threading.Lock()
def safe_increment(steps):
global shared_counter
for _ in range(steps):
# 使用上下文管理器自动处理加锁与解锁,避免忘记 release 导致死锁
with lock:
current = shared_counter
time.sleep(0.001) # 模拟耗时操作放大竞态风险
shared_counter = current + 1
threads = [
threading.Thread(target=safe_increment, args=(5000,)),
threading.Thread(target=safe_increment, args=(5000,))
]
for t in threads:
t.start()
for t in threads:
t.join()
print(f"最终安全计数值: {shared_counter} (预期应为 10000)")
使用 Queue 队列进行通信
相较于共享全局变量,推荐使用 queue.Queue(先进先出)、LifoQueue 或 PriorityQueue 进行线程间数据交换。这些队列内置锁原语,天然支持多线程安全读写。
import queue
import threading
import time
def consumer(consumer_id, task_q):
while True:
try:
# block=False 可实现非阻塞拉取,配合空队列判断控制退出
item = task_q.get_nowait()
except queue.Empty:
break
print(f"消费者 {consumer_id} 处理任务: {item}")
time.sleep(0.5)
task_q.task_done() # 通知队列该任务已完成
work_q = queue.Queue(maxsize=10)
items_to_process = [f"Task-{i}" for i in range(5)]
# 填充队列
for item in items_to_process:
work_q.put(item)
# 启动消费者线程
c_threads = []
for idx in range(2):
ct = threading.Thread(target=consumer, args=(idx+1, work_q))
ct.daemon = True # 设为守护线程,随主线程退出而终止
ct.start()
c_threads.append(ct)
work_q.join() # 阻塞直到队列为空且所有任务标记为 done
print("全部数据消费完成。")
适用场景与注意事项
- GIL 限制:Cython/CPython 实现的全局解释器锁使得同一时刻仅有一个字节码指令执行。多线程无法利用多核加速纯计算型任务,此类场景应转向
multiprocessing。 - 适用领域:爬虫抓取、Web 服务端并发响应、批量 I/O 读写是典型的高收益场景。
- 优雅退出:避免在主循环使用
while 1: pass占用 CPU。应结合thread.join()或队列task_done/join()机制等待子线程安全收尾。
以上就是Python多线程入门学习的详细内容,更多关于Python并发编程的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













