selectselect
Go语言在select语句中实现优先级
select语句介绍
selectcaseswitchselectcasechannelselect
select {
case <-ch1:
fmt.Println("ai.52learn.online")
case ch2 <- 1:
fmt.Println("q1mi")
}
selectgoroutinech1ch2ch1ch2selectchannelcasechannelcase
select
空select
selectcase
select{
}
selectgoroutinegoroutine
只有一个case
selectcaseselectchannel
select {
case <-ch1:
fmt.Println("ai.52learn.online")
}
ch1
有default语句
selectdefaultcase
select {
case <-ch1:
fmt.Println("ai.52learn.online")
default:
time.Sleep(time.Second)
}
ch1defaultchannel
总结
selectcaseselectcaseselectcasecaseselectdefaultcasedefault
如何在select中实现优先级
selectcasecase
ch1ch2
ch1ch2
高级Go语言程序员小明挠了挠头写出了如下函数:
func worker(ch1, ch2 <-chan int, stopCh chan struct{}) {
for {
select {
case <-stopCh:
return
case job1 := <-ch1:
fmt.Println(job1)
default:
select {
case job2 := <-ch2:
fmt.Println(job2)
default:
}
}
}
}
selectch1ch2
怎么办呢?
小明又挠了挠头,又写下了另一个解决方案:
func worker2(ch1, ch2 <-chan int, stopCh chan struct{}) {
for {
select {
case <-stopCh:
return
case job1 := <-ch1:
fmt.Println(job1)
case job2 := <-ch2:
priority:
for {
select {
case job1 := <-ch1:
fmt.Println(job1)
default:
break priority
}
}
fmt.Println(job2)
}
}
}
selectforLABELselectjob2 := <-ch2selectjob1 := <-ch1ch1select
实际应用场景
selectselect
// kubernetes/pkg/controller/nodelifecycle/scheduler/taint_manager.go
func (tc *NoExecuteTaintManager) worker(worker int, done func(), stopCh <-chan struct{}) {
defer done()
// 当处理具体事件的时候,我们会希望 Node 的更新操作优先于 Pod 的更新
// 因为 NodeUpdates 与 NoExecuteTaintManager无关应该尽快处理
// -- 我们不希望用户(或系统)等到PodUpdate队列被耗尽后,才开始从受污染的Node中清除pod。
for {
select {
case <-stopCh:
return
case nodeUpdate := <-tc.nodeUpdateChannels[worker]:
tc.handleNodeUpdate(nodeUpdate)
tc.nodeUpdateQueue.Done(nodeUpdate)
case podUpdate := <-tc.podUpdateChannels[worker]:
// 如果我们发现了一个 Pod 需要更新,我么你需要先清空 Node 队列.
priority:
for {
select {
case nodeUpdate := <-tc.nodeUpdateChannels[worker]:
tc.handleNodeUpdate(nodeUpdate)
tc.nodeUpdateQueue.Done(nodeUpdate)
default:
break priority
}
}
// 在 Node 队列清空后我们再处理 podUpdate.
tc.handlePodUpdate(podUpdate)
tc.podUpdateQueue.Done(podUpdate)
}
}
}
总结
selectselect
最后多嘴一句,Go语言由于自身没有很多奇怪的语法糖和自带代码格式化,相比其他语言来说并不会存在看不懂别人写的代码的情况。所以我们完全可以通过阅读优秀库的源代码,与巨人为伍,与高朋为伴,最终吃上更好的饭。