我们如何在go频道上设置诸如监听器之类的功能,以便当有人从该频道中读取某些内容时通知我们?
想象一下,我们有一个sequence number
的频道条目,当有人从我们包装中某处的频道中读取某个值时,我们想将其递减。
答案 0 :(得分:1)
未缓冲的通道同步传递数据,因此您已经知道何时读取数据。当缓冲区已满时,缓冲通道的工作方式类似,但是否则它们不会阻塞相同的通道,因此这种方法不会告诉您完全相同的事情。根据您的实际需求,还考虑使用sync.WaitGroup之类的工具。
ch = make(chan Data)
⋮
for {
⋮
// make data available
ch <- data
// now you know it was read
sequenceNumber--
⋮
}
答案 1 :(得分:1)
您可以创建通道中继机制,以实时捕获读取事件。
例如:
func relayer(in <-chan MyStruct) <-chan MyStruct {
out := make(chan MyStruct) // non-buffered chan (see below)
go func() {
defer close(out)
readCountLimit := 10
for item := range in {
out <- item
// ^^^^ so this will block until some worker has read from 'out'
readCountLimit--
}
}()
return out
}
用法:
type MyStruct struct {
// put your data fields here
}
ch := make(chan MyStruct) // <- original channel - used by producer to write to
rch := relayer(ch) // <- relay channel - used to read from
// consumers
go worker("worker 1", rch)
go worker("worker 2", rch)
// producer
for { ch <- MyStruct{} }
答案 2 :(得分:0)
您可以在手动模式下进行操作。在邮件中实现某种ACK
标记。
像这样:
type Msg struct {
Data int
ack bool
}
func (m *Msg) Ack() {
m.ack = true
}
func (m *Msg) Acked() bool {
return m.ack
}
func main() {
ch := make(chan *Msg)
msg := &Msg{Data: 1}
go func() {
for {
if msg.Acked() {
// do smth
}
time.Sleep(10 * time.Second)
}
}()
ch <- msg
for msg := range ch {
msg.Ack()
}
}
代码未经测试。
您还可以在Ack()
方法中添加一些其他信息,例如关于package和func的元信息,从那里调用Ack()
,此答案可能与以下内容有关:https://stackoverflow.com/a/35213181/3782382