Python 线程 Threading
1. 基本概念
- 线程(Thread):操作系统可调度的最小执行单元,属于进程(Process)的一部分。一个进程可以包含多个线程,线程之间共享进程的内存空间。
- 进程(Process):具有独立内存空间和资源的运行实例。进程之间相互独立。
线程优点:
- 轻量级,创建和切换开销小。
- 适合 I/O 密集型任务。
线程缺点:
- 多线程共享同一内存,需注意同步和数据安全。
![]()
2. 创建线程
2.1 函数式创建
from threading import Thread
import threading, time
def task(name, rounds=3):
for i in range(rounds):
time.sleep(1)
print(f"线程 {name} 执行第 {i} 次")
if __name__ == '__main__':
print("主线程开始")
threads = [Thread(target=task, args=(f"T{i+1}",)) for i in range(2)]
for t in threads: t.start()
for t in threads: t.join()
print("主线程结束")
Thread(target=..., args=...):指定目标函数和参数。start():启动线程,调用run()方法。join():阻塞主线程,直到该线程执行结束。
2.2 子类化创建
from threading import Thread
import threading, time
class MyThread(Thread):
def __init__(self, name, rounds=3):
super().__init__(name=name)
self.rounds = rounds
def run(self):
for i in range(self.rounds):
time.sleep(1)
print(f"线程 {self.name} 执行第 {i} 次")
if __name__ == '__main__':
print("主线程开始")
threads = [MyThread(name=f"T{i+1}") for i in range(2)]
for t in threads: t.start()
for t in threads: t.join()
print("主线程结束")
- 通过继承
Thread并重载run()方法,封装更强。
3. 数据共享与安全
- 多线程共享全局变量或对象实例。
- 示例:
from threading import Thread
import time
a = 100
def add():
global a
a += 30
print(f"加后: {a}")
def sub():
global a
a -= 50
print(f"减后: {a}")
if __name__ == '__main__':
print(f"初始: {a}")
t1 = Thread(target=add)
t2 = Thread(target=sub)
t1.start(); t2.start()
t1.join(); t2.join()
print(f"最终: {a}")
- 问题:线程执行顺序不确定,可能产生竞态条件(Race Condition),导致数据不一致。
3.1 锁(Lock)
from threading import Thread, Lock
import time
a = 100
lock = Lock()
def safe_add():
global a
with lock:
tmp = a
time.sleep(0.1)
a = tmp + 30
print(f"加后: {a}")
def safe_sub():
global a
with lock:
tmp = a
time.sleep(0.1)
a = tmp - 50
print(f"减后: {a}")
if __name__ == '__main__':
threads = [Thread(target=safe_add), Thread(target=safe_sub)]
for t in threads: t.start()
for t in threads: t.join()
print(f"最终: {a}")
- 使用
Lock或RLock保护临界区,确保同一时刻只有一个线程访问共享资源。
4. 生产者-消费者模型
通过 queue.Queue 实现线程间安全的数据交换:
| 方法 | 作用 |
|---|---|
put(item) |
放入队列,队列满时阻塞 |
get() |
取出队列,队列空时阻塞 |
task_done() |
通知队列任务完成 |
join() |
等待队列中所有任务完成 |
from queue import Queue
from threading import Thread
import time
class Producer(Thread):
def __init__(self, queue):
super().__init__()
self.queue = queue
def run(self):
for i in range(3):
print(f"生产: {i}")
self.queue.put(i)
time.sleep(1)
print("生产者完成")
class Consumer(Thread):
def __init__(self, queue):
super().__init__()
self.queue = queue
def run(self):
while True:
item = self.queue.get()
print(f"消费: {item}")
self.queue.task_done()
if __name__ == '__main__':
q = Queue()
producers = [Producer(q) for _ in range(1)]
consumers = [Consumer(q) for _ in range(1)]
for c in consumers: c.daemon = True; c.start()
for p in producers: p.start()
for p in producers: p.join()
q.join()
print("主线程结束")
- 设置消费者为守护线程(daemon),主线程退出后自动结束。
5. 小结
-
使用场景:I/O 密集型适合多线程,CPU 密集型推荐多进程(
multiprocessing)。 -
同步工具:
Lock、RLock、Semaphore、Event、Condition等。 -
线程池:
concurrent.futures.ThreadPoolExecutor简化线程管理。 -
调试技巧:避免死锁、使用日志打印线程名与操作。


浙公网安备 33010602011771号