# #go #ethereum #channel
Вопрос:
func (m *FairMix) runSource(closed chan struct{}, s *mixSource) {
defer m.wg.Done()
defer close(s.next)
for s.it.Next() {
n := s.it.Node()
fmt.Println("discmix Addsource : ", n.ID())
select {
case s.next <- n:
fmt.Println("s.next <- n :", n.ID())
case m.fromAny <- n:
fmt.Println("m.fromAny <- n :", n.ID())
case <-closed:
return
}
}
}
Это код Ethereum geth 1.9.25 в.
В select
операции эти две s.next
m.fromAny
переменные amp; оба ждут n
.
Но когда я запускаю программу, case s.next <- n
ее выбирают чаще по сравнению с case m.fromAny <- n
.
Могу ли я знать, какое дело будет выбрано первым? Существует ли какой-то алгоритм выбора случаев, если несколько случаев готовы?
Комментарии:
1. Каналы Ok отправляют значение только один раз, поэтому, когда вы делаете это, s.Next и s.fromAny находятся в состоянии ожидания, и невозможно определить, кто получит значение. tour.golang.org/concurrency/2
Ответ №1:
Я бы порекомендовал вам отправиться на экскурсию. В Go Tour у них есть легко понятная практическая игровая площадка, где они select
также рассказывали о поведении.
Ссылка для перехода в тур по выбору
Таким образом, a select
блокируется до тех пор, пока один из его случаев не сможет выполняться, затем он выполняет этот случай. Он выбирает один наугад, если готовы несколько.
И дело не только в n
этом, но и в s.next
том, чтобы и m.fromAny
.
Итак, давайте рассмотрим эти два случая:
// For this case to be selected s.next should be ready
case s.next <- n
// For this case to be selected m.fromAny should be ready
case m.fromAny <- n
Итак, предположим s.next
, и m.fromAny
оба готовы одновременно, любой случай может быть выбран случайным образом (также описано в определении).
n
доступно, поэтому это зависит от каналов приемника: s.next
и m.fromAny
.
Следовательно, мы не можем точно решить, какой случай будет выбран, если несколько готовы.