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 關注
- 281 瀏覽
添加回答
舉報