Python脚本如何实现线程等待唤醒

wen python案例 30

本文目录导读:

Python脚本如何实现线程等待唤醒

  1. 使用 Event(最常用)
  2. 使用 Condition(支持精确唤醒)
  3. 使用 Semaphore(信号量)
  4. 使用 queue.Queue(生产者-消费者模式)
  5. 选择建议
  6. 注意事项

在Python中实现线程的等待与唤醒,主要使用threading模块中的EventConditionSemaphore等同步原语,以下是几种常见实现方式:

使用 Event(最常用)

Event是最简单的线程间通信机制,支持 wait()set()/clear()

import threading
import time
# 创建事件对象
event = threading.Event()
def waiter():
    print("等待者:等待事件...")
    event.wait()  # 阻塞等待事件被设置
    print("等待者:接收到事件,继续执行")
def setter():
    print("设置者:准备设置事件")
    time.sleep(3)  # 模拟一些工作
    event.set()    # 设置事件,唤醒等待线程
    print("设置者:事件已设置")
# 创建线程
t1 = threading.Thread(target=waiter)
t2 = threading.Thread(target=setter)
t1.start()
t2.start()
t1.join()
t2.join()

使用 Condition(支持精确唤醒)

Condition提供更细粒度的控制,可以结合 notify()/notify_all() 精确唤醒。

import threading
import time
condition = threading.Condition()
shared_data = []
DATA_READY = False
def consumer():
    with condition:
        print("消费者:等待数据...")
        while not DATA_READY:  # 必须用while循环检查条件
            condition.wait()  # 释放锁并等待
        print("消费者:获取到数据:", shared_data)
def producer():
    global DATA_READY
    time.sleep(2)  # 模拟生产数据
    with condition:
        shared_data.append("重要数据")
        DATA_READY = True
        print("生产者:通知消费者")
        condition.notify()  # 唤醒一个等待线程
t1 = threading.Thread(target=consumer)
t2 = threading.Thread(target=producer)
t1.start()
t2.start()
t1.join()
t2.join()

使用 Semaphore(信号量)

信号量控制同时访问资源的线程数量,也可用于线程间同步。

import threading
import time
semaphore = threading.Semaphore(0)  # 初始值为0
def waiter():
    print("等待者:等待信号量...")
    semaphore.acquire()  # 阻塞等待信号量>0
    print("等待者:获得信号量,继续执行")
def setter():
    print("设置者:释放信号量")
    time.sleep(2)
    semaphore.release()  # 释放信号量,增加计数
t1 = threading.Thread(target=waiter)
t2 = threading.Thread(target=setter)
t1.start()
t2.start()

使用 queue.Queue(生产者-消费者模式)

对于简单的数据传递场景,使用队列更安全、更方便。

import threading
import time
import queue
q = queue.Queue()
def consumer():
    print("消费者:等待数据...")
    data = q.get()  # 阻塞等待队列非空
    print("消费者:获取到:", data)
def producer():
    time.sleep(2)
    data = "重要数据"
    q.put(data)  # 放入队列
    print("生产者:已放入数据")
t1 = threading.Thread(target=consumer)
t2 = threading.Thread(target=producer)
t1.start()
t2.start()

选择建议

场景 推荐方案 说明
简单一次性等待 Event 最简洁,适合一次性的通知
条件精确控制 Condition 支持精确唤醒特定线程
资源访问控制 Semaphore 控制并发访问数量
数据传递 Queue 线程安全的队列,自动处理同步
周期性任务 Timer 定时执行特定功能

注意事项

  1. 虚假唤醒:使用Condition时,必须用while循环检查条件
  2. 死锁预防:确保锁的获取和释放成对出现,避免嵌套锁
  3. 超时处理:大多数等待方法支持timeout参数
  4. 线程安全:共享数据的读写需要在锁的保护下进行
# 带超时的等待示例
event = threading.Event()
event.wait(timeout=5)  # 最多等待5秒
if event.is_set():
    print("事件已设置")
else:
    print("等待超时")

根据具体需求选择合适的同步机制,可以让线程间的协作更加高效和安全。

抱歉,评论功能暂时关闭!