5 回答
TA贡献1816条经验 获得超4个赞
最好将通道视为队列 (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
}
这使用 aRWMutex这意味着许多东西可以同时从中读取,而只有一个东西可以写入。它将像您所说的那样存储一个条目。
TA贡献1824条经验 获得超6个赞
不,通道是 FIFO 缓冲区,句号。这就是渠道的运作方式及其唯一目的。如果您只想要最新的值,请考虑只使用一个受互斥锁保护的变量;每当有新数据进入时写入它,无论何时读取它,您将始终读取最新值。
TA贡献1789条经验 获得超8个赞
你不能直接从一个通道获取它,但你可以为每个值使用一个通道,并在有新值时得到通知:
package main
import (
"fmt"
"strconv"
"sync"
"time"
)
type LatestChannel struct {
n float64
next chan struct{}
mu sync.Mutex
}
func New() *LatestChannel {
return &LatestChannel{next: make(chan struct{})}
}
func (c *LatestChannel) Push(n float64) {
c.mu.Lock()
c.n = n
old := c.next
c.next = make(chan struct{})
c.mu.Unlock()
close(old)
}
func (c *LatestChannel) Get() (float64, <-chan struct{}) {
c.mu.Lock()
n := c.n
next := c.next
c.mu.Unlock()
return n, next
}
func getSensorData(c *LatestChannel) {
time.Sleep(1 * time.Second)
c.Push(2.1)
time.Sleep(100 * time.Millisecond)
c.Push(2.2)
time.Sleep(100 * time.Millisecond)
c.Push(2.3)
time.Sleep(100 * time.Millisecond)
c.Push(2.4)
time.Sleep(100 * time.Millisecond)
c.Push(2.5)
}
func main() {
s := 1.1
c := New()
_, hasNext := c.Get()
go getSensorData(c)
for {
select {
case <-hasNext:
s, hasNext = c.Get()
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(250 * time.Millisecond) // Do heavy "work"
}
}
TA贡献1866条经验 获得超5个赞
试试这个包https://github.com/subbuv26/chanup
它允许生产者用最新值更新通道,从而替换最新值。并且产品不会被阻止。(有了这个,过时的值被覆盖)。因此,在消费者方面,总是只读取最新的项目。
import "github.com/subbuv26/chanup"
ch := chanup.GetChan()
_ := ch.Put(testType{
a: 10,
s: "Sample",
})
_ := ch.Update(testType{
a: 20,
s: "Sample2",
})
// Continue updating with latest values
...
...
// On consumer end
val := ch.Get()
// val contains latest value
- 5 回答
- 0 关注
- 138 浏览
添加回答
举报