threading模块学习

最近在celery源码学习中经常看到event库的使用,想结合源码学习,重温threading.event()的使用

threading.Event 是 Python 标准库 threading 模块中的一个线程同步原语,用于线程间的等待与通知。它允许一个或多个线程等待某个"事件"发生(即事件被 set),而其它线程可以在合适的时机触发该事件。常用于线程间通信、同步、生产者-消费者等场景。


主要特性

  • 事件标志:内部维护一个布尔标志,初始为 False。
  • set():将事件标志设为 True,唤醒所有等待的线程。
  • clear():将事件标志设为 False,等待的线程会阻塞。
  • wait(timeout=None):阻塞当前线程,直到事件标志为 True 或超时。
  • is_set():查询事件标志当前状态。

1. 基本等待与通知

python 复制代码
import threading
import time

event = threading.Event()

def worker():
    print("Worker: 等待事件...")
    event.wait()
    print("Worker: 事件已触发,开始工作!")

t = threading.Thread(target=worker)
t.start()

time.sleep(2)
print("主线程: 2秒后触发事件")
event.set()
t.join()

输出:

makefile 复制代码
Worker: 等待事件...
主线程: 2秒后触发事件
Worker: 事件已触发,开始工作!

2. 多线程同时等待同一个事件

python 复制代码
import threading
import time

event = threading.Event()

def worker(n):
    print(f"Worker {n}: 等待事件...")
    event.wait()
    print(f"Worker {n}: 事件已触发,开始工作!")

threads = [threading.Thread(target=worker, args=(i,)) for i in range(3)]
for t in threads: t.start()

time.sleep(1)
print("主线程: 1秒后触发事件")
event.set()
for t in threads: t.join()

输出:

yaml 复制代码
Worker 0: 等待事件...
Worker 1: 等待事件...
Worker 2: 等待事件...
主线程: 1秒后触发事件
Worker 0: 事件已触发,开始工作!
Worker 1: 事件已触发,开始工作!
Worker 2: 事件已触发,开始工作!

3. 超时等待

python 复制代码
import threading
import time

event = threading.Event()

def worker():
    print("Worker: 最多等待3秒...")
    flag = event.wait(timeout=3)
    if flag:
        print("Worker: 事件已触发!")
    else:
        print("Worker: 超时未触发事件,继续执行...")

t = threading.Thread(target=worker)
t.start()

time.sleep(5)
event.set()
t.join()

输出:

makefile 复制代码
Worker: 最多等待3秒...
Worker: 超时未触发事件,继续执行...

4. 多次触发与清除

python 复制代码
import threading
import time

event = threading.Event()

def worker():
    while True:
        print("Worker: 等待事件...")
        event.wait()
        print("Worker: 事件已触发,工作一次!")
        event.clear()  # 清除事件,进入下一轮等待

t = threading.Thread(target=worker, daemon=True)
t.start()

for i in range(3):
    time.sleep(1)
    print(f"主线程: 第{i+1}次触发事件")
    event.set()

time.sleep(2)

输出:

makefile 复制代码
Worker: 等待事件...
主线程: 第1次触发事件
Worker: 事件已触发,工作一次!
Worker: 等待事件...
主线程: 第2次触发事件
Worker: 事件已触发,工作一次!
Worker: 等待事件...
主线程: 第3次触发事件
Worker: 事件已触发,工作一次!
Worker: 等待事件...

5. 生产者-消费者模型(事件控制)

python 复制代码
import threading
import time

event = threading.Event()
data = []

def producer():
    for i in range(5):
        time.sleep(1)
        data.append(i)
        print(f"Producer: 生产数据 {i}")
        event.set()  # 通知消费者有新数据
        event.clear()

def consumer():
    for _ in range(5):
        print("Consumer: 等待新数据...")
        event.wait()
        print(f"Consumer: 消费数据 {data[-1]}")

t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)
t1.start()
t2.start()
t1.join()
t2.join()

输出:

makefile 复制代码
Consumer: 等待新数据...
Producer: 生产数据 0
Consumer: 消费数据 0
Consumer: 等待新数据...
Producer: 生产数据 1
Consumer: 消费数据 1
Consumer: 等待新数据...
Producer: 生产数据 2
Consumer: 消费数据 2
Consumer: 等待新数据...
Producer: 生产数据 3
Consumer: 消费数据 3
Consumer: 等待新数据...
Producer: 生产数据 4
Consumer: 消费数据 4

总结

  • threading.Event 适合多线程同步、等待、通知、超时等场景。
  • 通过 set/clear/wait/is_set 方法实现灵活的线程间通信。
  • 可用于生产者-消费者、批量唤醒、超时控制等多种并发模式。
相关推荐
2601_9547064913 分钟前
云手机 API 自动化实战:Python 批量控机、挂机脚本完整实现
python·智能手机·自动化
Alan_6914 小时前
聊聊 Swagger/Postman/Apifox 的真实选型与 Python 项目实战
python·测试工具·postman
智慧物业老杨5 小时前
物业绿化数智化权责管控方案:基于工单平台的双层权限追溯模块落地实践
python
Metaphor6925 小时前
使用 Python 在 Word 文档中添加批注
python·word
FreakStudio6 小时前
WIZnet 开源方案分享:W55MH32 开发板 + 小智 AI实现以太网版本的小智机器人
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
会周易的程序员6 小时前
使用 pybind11 封装 C++ 日志库 microLog 为 Python 模块
java·c++·python·物联网·架构·日志·aiot
一只专注api接口开发的技术猿6 小时前
电商评论自动化监控与情感数据分析完整落地教程(附可直接运行 Python 代码)
大数据·数据库·python·数据分析·自动化
HAPPY酷6 小时前
【ROS2】 Conda 环境搭建(命令行版)
linux·运维·python·ubuntu·机器人·conda
柒和远方7 小时前
LeetCode 4. 寻找两个正序数组的中位数 —— 二分划分的艺术
javascript·python·算法
学也学不废8 小时前
Flask问答系统与LAUR模型
人工智能·python·机器学习·分类·数据挖掘