英文:
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
通道来进行速率限制和节流 - 如果你想要丢弃事件,可以使用带有select
和case 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 <- msg:
default:
}
}
}()
and to read:
for msg := range ch {
Info.Printf("throttled: %s", msg)
time.Sleep(1000 * time.Millisecond) // throttle 1 message/s
}
Working example:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论