go - 如何始终从 Go 频道获取最新值?
问题描述
我从 Go 开始,现在正在编写一个简单的程序,该程序从传感器读取数据并将其放入通道中以对其进行一些计算。我现在的工作方式如下:
package main
import (
"fmt"
"time"
"strconv"
)
func get_sensor_data(c chan float64) {
time.Sleep(1 * time.Second) // wait a second before sensor data starts pooring in
c <- 2.1 // Sensor data starts being generated
c <- 2.2
c <- 2.3
c <- 2.4
c <- 2.5
}
func main() {
s := 1.1
c := make(chan float64)
go get_sensor_data(c)
for {
select {
case s = <-c:
fmt.Println("the next value of s from the channel: " + strconv.FormatFloat(s, 'f', 1, 64))
default:
// no new values in the channel
}
fmt.Println(s)
time.Sleep(500 * time.Millisecond) // Do heavy "work"
}
}
这很好用,但是传感器会生成大量数据,而我总是只对最新数据感兴趣。但是,使用此设置时,它只会在每个循环中读取下一项,这意味着如果通道在某个时间点包含 20 个值,则仅在 10 秒后读取最新值。
有没有办法让通道总是一次只包含一个值,这样我总是只得到我感兴趣的数据,并且通道没有使用不必要的内存(尽管内存是我最不担心的) )?
解决方案
最好将通道视为队列 (FIFO)。因此,您不能真正跳过。然而,有一些库可以做这样的事情:https ://github.com/cloudfoundry/go-diodes是一个原子环形缓冲区,它将覆盖旧数据。如果您愿意,可以设置较小的尺寸。
话虽如此,听起来您并不需要队列(或环形缓冲区)。你只需要一个互斥锁:
type SensorData struct{
mu sync.RWMutex
last float64
}
func (d *SensorData) Store(data float64) {
mu.Lock()
defer mu.Unlock()
d.last = data
}
func (d *SensorData) Get() float64 {
mu.RLock()
defer mu.RUnlock()
return d.last
}
这使用了 a RWMutex
,这意味着许多东西可以同时从中读取,而只有一个东西可以写入。就像你说的那样,它将存储一个条目。
推荐阅读
- d3.js - 如何在 d3 图表中添加 highcharts export.js 以进行导出
- python - 将字符串在 Pandas 数据框中出现的次数附加到另一列
- javascript - 如何在angularjs中使用标签进行搜索
- python-3.x - 未找到 win32gui 模块
- python - 从列表列表创建字典
- mysql - Freeradius 显示不正确的在线用户数与 NAS
- mockito - mockito - 模拟不同包中的受保护方法
- java - 使用 Apache FOP 时波兰语特殊字母不可用
- r - 对 ANN 的输出进行缩放
- javascript - 如何让 react.js 中的 render() 等待我的数组填充来自 xml 的对象