2 回答
TA贡献2051条经验 获得超10个赞
最近有一篇来自 MongoDB 的人的文章。显然,此代码在其实用mongodump程序中用于生产。
使用的具体代码reflect.Select如下所示(来自文章):
// Run multiplexer until it receives an EOF on the control channel.
func (mux *Multiplexer) Run() {
for {
index, value, recv := reflect.Select(mux.selectCases)
EOF := !recv
// note that the control channel is always at index 0
if index == 0 {
if EOF {
return
}
muxInput, _ := value.Interface().(*muxInputSource)
mux.selectCases = append(mux.selectCases, reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(muxInput.collection),
Send: reflect.Value{},
})
} else {
if EOF {
mux.writeEOF()
mux.selectCases = append(mux.selectCases[:index], mux.selectCases[index+1:]...)
} else {
document, _ := value.Interface().([]byte)
mux.writeDocument(document)[]
}
}
}
}
我认为他们使用reflect.Select而不是直接的原因select:
goroutine 的数量(以及通道的数量)是在运行时确定的(使用-j标志)。事实上,它似乎随着append. (归功于@cnicutar 的评论)
通道的类型在运行时确定。这允许他们的muxInput.collection类型是任何它想要的。(归功于@JimB 的评论)
TA贡献1860条经验 获得超8个赞
如果您的频道是固定的,您可以使用选择观看它们;但是,如果您的频道不固定并且您想观看它们,则可以使用 reflect.Select。
有一些代码片段
var (
events []reflect.SelectCase
err error
lenHdr = 3 // zk conn event chan, shutdown chan, children refresh chan
lenCW = len(z.ChildWatches) // a channel slice:chan ChildWatche
lenDW = len(z.DataWatches) //a channel slice:chan DataWatche
lenEN = len(z.EphemeralNodes) //a channel slice: chan EphemeralNode
)
events = make([]reflect.SelectCase, lenHdr+lenCW+lenDW+lenEN)
events[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(FreshChanConEvent())} // kick off the event loop
events[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(z.shutdownChan)}
events[2] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(z.refreshChildChan)}
for i, _ := range z.ChildWatches {
events[lenHdr+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.Zero(reflect.TypeOf((chan zk.Event)(nil)))}
}
for i, _ := range z.DataWatches {
events[lenHdr+lenCW+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.Zero(reflect.TypeOf((chan zk.Event)(nil)))}
}
for i, info := range z.EphemeralNodes {
events[lenHdr+lenCW+lenDW+i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(info.Ch)}
}
for {
chosen, value, ok := reflect.Select(events)
if chosen == xxxxx {...}
这段代码是看频道数组(z.ChildWatches、z.DataWatches、z.EphemeralNodes)
- 2 回答
- 0 关注
- 243 浏览
添加回答
举报