You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python线程中无法从Queue获取消息的问题排查

问题分析与解决方案

核心问题

你的代码无法从队列获取值,主要原因有两个:

  1. Python版本API错误:Python3中Thread类的存活状态判断方法是is_alive(),而非Python2时期的isAlive()。原代码中print(f'Thread is {self.isAlive()}')会触发AttributeError,导致线程启动后直接崩溃,根本执行不到后续的队列取值逻辑。
  2. 队列选型不当:线程间通信应使用线程安全的queue.Queue,multiprocessing.Queue是为进程间通信设计的,虽然线程也能使用,但没必要,且可能引入不必要的复杂度。

修正后的代码

TemperatureSensorThread.py

from threading import Thread
from src.sensor import PowerSetting, TemperatureSensor
import queue  # 使用线程安全的queue模块

class TemperatureSensorThread(Thread):

    def __init__(self, q: queue.Queue):
        super().__init__()
        self.sensor = TemperatureSensor('temperature_sensor')
        self.q = q
        self.last_temp = -1
        self.last_pow_setting = PowerSetting.POWER_OFF

    def run(self) -> None:
        should_continue = True
        while should_continue:
            print(f'Thread is {self.is_alive()}')  # 修正为is_alive()
            try:
                # 可选:添加超时,避免线程无限阻塞
                message: dict = self.q.get(timeout=1)
            except queue.Empty:
                continue
            print(f'Queue message\t{message}')
            _action = message.get('action')
            _temp = message.get('temp')

            sensor_temp = self.last_temp  
            pow_setting = self.last_pow_setting 
            if _action == 'exit':
                should_continue = False
                break

            if _temp is not None:
                sensor_temp = _temp
            if _action == 'start':
                pow_setting = PowerSetting.POWER_ON
            elif _action == 'stop':
                pow_setting = PowerSetting.POWER_OFF

            self.sensor.set_temperature(sensor_temp)
            self.sensor.turn_on_off(power_setting=pow_setting)

            self.last_pow_setting = pow_setting
            self.last_temp = sensor_temp

Client.py

from src.temperature_sensor_thread import TemperatureSensorThread
import queue  # 使用线程安全的queue模块
import time

temp_q: queue.Queue = queue.Queue()

t = TemperatureSensorThread(q=temp_q)
t.start()
print('Setting temp 32')
temp_q.put({'temp': 32})

print('Action: START')
temp_q.put({'action': 'start'})
time.sleep(4)

print('Action: STOP')
temp_q.put({'action': 'stop'})
time.sleep(3)

print('Temp: 41')
temp_q.put({'temp': 41})
time.sleep(3)

print('Action: START')
temp_q.put({'action': 'start'})
time.sleep(3)

print('Action: Exit')
temp_q.put({'action': 'exit'})
time.sleep(5)
print('Code exit')

额外说明

  • 给q.get()添加timeout并捕获queue.Empty异常,是为了避免线程在队列无消息时一直阻塞,让线程能周期性检查是否需要退出(也可以用q.get_nowait(),但需要处理异常)。
  • 优化了消息处理的逻辑,让代码更清晰,避免不必要的三元表达式嵌套。

内容的提问来源于stack exchange,提问作者Vikas Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:16:11