使用Go语言每隔n秒从设备读取输入,并每隔m秒发送数据。

huangapple go评论95阅读模式
英文:

Read input every n seconds from device sending every m seconds using Go

问题

使用Go语言,我想从连接到串口的设备中每秒读取一次日志,该设备每300毫秒发送一个以换行符结尾的日志。我认为通过串口连接这一点应该是无关紧要的。我应该如何每秒读取一条新的日志条目,并丢弃其他条目,因为设备每300毫秒写入一条日志?

英文:

Using Go, I want to read every 1 second from a device connected to the serial port that sends a log terminated with a newline character every 300 ms. The fact that this is via the serial port should be immaterial, I believe. How can I read a new log entry every 1 second and dropping the other entries, since the device is writing log entries every 300 ms?

答案1

得分: 1

记住上次处理日志条目的时间。循环读取日志条目。如果距离上次日志的时间大于所需的频率,则处理日志并更新上次日志时间。

freq := time.Second
prev := time.Time{}
for {
log := readLog()
if time.Since(prev) > freq {
prev = time.Now()
// 对日志进行处理
}
}

英文:

Remember the last time a log entry was processed. Read log entries in a loop. If time since log is greater than the desired frequency, process log and update last log time.

freq := time.Second
prev := time.Time{}
for {
	log := readLog()
	if time.Since(prev) > freq {
	        prev = time.Now()
		    // do something with log
	}
}

答案2

得分: 1

你可以使用Go通道来进行速率限制和节流 - 如果你想要丢弃事件,可以使用带有selectcase default:的缓冲通道来实现非阻塞的通道写入。

所以,一个简单的轮询实现(类似于@BurakSerdar建议的方式 - 但是消息会被丢弃直到有一个被读取 - 但是产生相同的结果):

ch := make(chan string, 1) // 1 - 所以我们至少保留一个消息
go func() {
    for {
        msg := getLog()
        
        // 非阻塞写入,即消息可能会被丢弃
        select {
        case ch <- msg:
        default:
        }
    }
}()

// 读取:
for msg := range ch {
    Info.Printf("throttled: %s", msg)
    time.Sleep(1000 * time.Millisecond) // 每秒节流1条消息
}

工作示例:

https://play.golang.org/p/_QIBGal4_jJ

英文:

You can use Go channels to rate-limit and throttle - and if you want to drop events, a buffered channel with select combined with case default: allows for non-blocking channel writes.

So, a simple polling implementation (similar to what @BurakSerdar suggested - but instead messages are dropped until one is read - but yields the same result):

ch := make(chan string, 1) // 1 - so we keep at least one message
go func() {
	for {
		msg := getLog()
		
        // non-blocking write i.e. messages may be dropped
		select {
		case ch &lt;- msg:
		default:
		}
	}
}()

and to read:

for msg := range ch {
	Info.Printf(&quot;throttled: %s&quot;, msg)
	time.Sleep(1000 * time.Millisecond) // throttle 1 message/s
}

Working example:

https://play.golang.org/p/_QIBGal4_jJ

huangapple
  • 本文由 发表于 2021年9月15日 09:18:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/69186063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定