doumin4553 2018-12-13 22:05
浏览 40
已采纳

如何始终从golang渠道获取最新价值?

I'm starting out with Go and I'm now writing a simple program which reads out data from a sensor and puts that into a channel to do some calculations with it. I now have it working as follows:

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"
    }
}

This works fine, but the sensor generates a lot of data, and I'm always only interested in the latest data. With this setup however, it only reads out the next item with every loop, which means that if the channel at some point contains 20 values, the newest value only is read out after 10 seconds.

Is there a way for a channel to always only contain one value at a time, so that I always only get the data I'm interested in, and no unnecessary memory is used by the channel (although the memory is the least of my worries)?

All tips are welcome!

  • 写回答

3条回答 默认 最新

  • douhanzhen8927 2018-12-13 22:15
    关注

    Channels are best thought of as queues (FIFO). Therefore you can't really skip around. However there are libraries out there that do stuff like this: https://github.com/cloudfoundry/go-diodes is an atomic ring buffer that will overwrite old data. You can set a smaller size if you like.

    All that being said, it doesn't sound like you need a queue (or ring buffer). You just need a mutex:

    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
    }
    

    This uses a RWMutex which means many things can read from it at the same time while only a single thing can write. It will store a single entry much like you said.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 关于cpci总线的几个问题,有点迷糊
  • ¥15 乳腺癌数据集 相关矩阵 特征选择
  • ¥15 我的游戏账号被盗取,请问我该怎么做
  • ¥15 通关usb3.0.push文件,导致usb频繁断连
  • ¥15 有没有能解决微信公众号,只能实时拍照,没有选择相册上传功能,我不懂任何技术,,有没有给我发个软件就能搞定的方法
  • ¥15 Pythontxt文本可视化
  • ¥15 如何基于Ryu环境下使用scapy包进行数据包构造
  • ¥15 springboot国际化
  • ¥15 搭建QEMU环境运行OP-TEE出现错误
  • ¥15 Minifilter文件保护