一尘不染

更新未读频道数据

go

有没有一种方法可以使用更多最新数据来更新发送到通道的未读数据?

我有一个goroutine(生产者),其频道提供了对另一个goroutine(消费者)的进度更新。在某些情况下,进度可以比消费者使用更新消息快得多。

这给我带来了问题,因为我可以:

  • 阻止将数据发送到通道。这意味着,如果使用者读取数据的速度较慢,则进度更新goroutine会完全阻塞-不应这样做。
  • 频道已满时,请勿阻止发送并跳过进度更新。这意味着使用者总是从数据中读取旧数据。

例如,我可能有这样的事情:

Progress reporting goroutine: Posts "1%" to channel Progress reporting goroutine: Posts "2%" to channel Progress reporting goroutine: Posts "3%" to channel Progress consuming goroutine: Reads "1%", "2%" and "3%" from channel. "1% and "2%" are outdated information.

有什么方法可以更新未读的频道数据吗?还是有解决此问题的更好方法?


阅读 249

收藏
2020-07-02

共1个答案

一尘不染

您可以将某些值存储在受其保护的全局变量中,以RWMutex 保持进度。生成器更新它。消费者阅读和表演。

您也可以对长度为1的通道进行非阻塞写入:

var c = make(chan struct{}, 1)
select {
case c <- struct{}{}:
default:
}

这样,发送方要么向通道添加一个元素,要么如果通道已满就什么都不做。

读者将此空结构视为信号-它应在全局变量中获取更新的值。

另一种方式: 可更新的频道

var c = make(chan int, 1)
select {
case c <- value:  // channel was empty - ok

default: // channel if full - we have to delete a value from it with some precautions to not get locked in our own channel
    switch {
    case <- c: // read stale value and put a fresh one
         c <- value
    default: // consumer have read it - so skip and not get locked
     }
}
2020-07-02