使用Go每隔1秒读取串口设备日志并丢弃多余条目如何实现
实现方案
核心思路
- 拆分两个独立协程分别处理串口读取和定时采样,避免逻辑阻塞
- 仅全局留存最新的一条日志记录,旧日志直接覆盖丢弃,无需缓存历史数据
- 用互斥锁保证共享日志变量的并发读写安全,避免数据竞争
具体实现步骤
1. 依赖说明
Go生态常用的串口操作库为go.bug.st/serial,可直接安装使用。
2. 代码实现示例
package main import ( "bufio" "fmt" "sync" "time" "go.bug.st/serial" ) func main() { // 串口配置,需根据实际设备参数调整 mode := &serial.Mode{ BaudRate: 9600, DataBits: 8, Parity: serial.NoParity, StopBits: serial.OneStopBit, } // 打开串口,路径根据实际系统调整:Windows下为COMx格式,Linux下为/dev/ttyUSBx这类格式 port, err := serial.Open("/dev/ttyUSB0", mode) if err != nil { panic(fmt.Sprintf("打开串口失败: %v", err)) } defer port.Close() var ( latestLog string logMu sync.Mutex ) // 协程1:持续读取串口日志,仅保留最新一条 go func() { scanner := bufio.NewScanner(port) for scanner.Scan() { line := scanner.Text() // 加锁更新最新日志,旧数据直接覆盖丢弃 logMu.Lock() latestLog = line logMu.Unlock() } if err := scanner.Err(); err != nil { fmt.Printf("串口读取异常: %v\n", err) } }() // 协程2:每隔1秒采样一次最新日志 ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() for range ticker.C { logMu.Lock() currentLog := latestLog // 可选配置:如果要求每次只取新产生的日志,取完后清空latestLog即可 // latestLog = "" logMu.Unlock() // 处理拿到的最新日志,这里仅做打印示例 if currentLog != "" { fmt.Printf("采集到最新日志: %s\n", currentLog) } else { fmt.Println("当前无新日志") } } }
注意事项
- 串口的波特率、数据位、停止位等配置必须和设备输出参数完全一致,否则会出现乱码或者读取失败
- 示例默认1秒内无新日志时会返回上一次采集到的日志,如有需要可以新增
hasNew布尔变量标记是否有未采集的新日志 - 生产环境可根据需求增加异常恢复逻辑,比如串口断开后自动重试重连
内容的提问来源于stack exchange,提问作者Matthew Rankin
相关产品推荐
相关产品推荐

