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

Python-CAN线程突发停止发送消息问题求助

Python线程驱动vcan0总线仅发送一次消息停止的问题解决

问题现象

  • 基于vcan0的CAN测试环境,模拟CAN模块脚本运行正常
  • 自定义CAN总线线程类启动后,仅主动发送一次消息就停止,无任何报错
  • 手动向vcan0发送消息时,脚本可以正常接收,但线程始终不再主动发送
  • 线程类的run_can_bus方法中print("0")仅执行一次
  • 脚本今早还能正常运行,怀疑与Python线程机制相关

原代码分析(问题版本)

import can
import threading
import time

class CANBusThread(threading.Thread):
    def __init__(self):
        super().__init__()
        self.bus = can.interface.Bus(channel='vcan0', bustype='socketcan')
        self.running = True

    def run(self):
        self.run_can_bus()

    def run_can_bus(self):
        print("0")
        # 主动发送逻辑在循环外,仅执行一次
        msg = can.Message(arbitration_id=0x123, data=[0x01, 0x02], is_extended_id=False)
        self.bus.send(msg)
        # 接收循环持续运行,但无主动发送逻辑
        while self.running:
            msg = self.bus.recv(1)
            if msg:
                print(f"Received: {msg}")

核心问题

  • 主动发送消息的代码块位于接收循环外部,仅在run_can_bus方法启动时执行一次,之后线程进入无限接收循环,无法再次触发主动发送
  • bus.recv(1)的1秒超时会阻塞线程,但即便超时,也没有回到主动发送的逻辑

修改后的解决代码

import can
import threading
import time

class CANBusThread(threading.Thread):
    def __init__(self):
        super().__init__()
        self.bus = can.interface.Bus(channel='vcan0', bustype='socketcan')
        self.running = True
        self.send_interval = 1  # 自定义主动发送间隔(秒)

    def run(self):
        self.run_can_bus()

    def run_can_bus(self):
        # 将主动发送与接收逻辑放入同一个循环内,保证持续执行
        while self.running:
            print("0")
            # 主动发送消息
            send_msg = can.Message(arbitration_id=0x123, data=[0x01, 0x02], is_extended_id=False)
            try:
                self.bus.send(send_msg)
                print(f"Sent message: {send_msg}")
            except can.CanError:
                print("Failed to send message")
            
            # 缩短接收超时时间,避免阻塞发送节奏
            recv_msg = self.bus.recv(0.1)
            if recv_msg:
                print(f"Received message: {recv_msg}")
            
            # 控制主动发送频率
            time.sleep(self.send_interval)

    def stop(self):
        # 安全停止线程
        self.running = False
        self.join()

修复说明

  1. 循环包裹逻辑:将主动发送代码移入while self.running循环内,保证线程持续执行主动发送操作
  2. 优化接收超时:把bus.recv(1)改为bus.recv(0.1),减少阻塞时间,避免影响主动发送的频率
  3. 增加异常捕获:为bus.send添加try-except块,便于排查发送失败的问题
  4. 添加线程停止方法:提供stop()方法,实现线程的安全退出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:10:16