Lendo simultaneidade em Go .
Tentando entender o padrão do canal or-done .
Estou com dificuldade para entender o fluxo de execução.
Mencionei o número na linha de onde vem minha dúvida.
Por que nenhuma
return
declaração em inner<-done
como temos em outerselect
? Por causa de nenhumareturn
declaração, a próxima iteração será executada e se nessa iteração tivermos ambos<- done
e<-c
disponíveis. Sabemosselect-case
que escolheremos qualquer um dos casos arbitrariamente se vários casos estiverem disponíveis. Isso significa que há uma possibilidade de que<-c
será executado mesmo se<-done
estiver disponível?Já que
select-case
arbitrariamente escolhe um caso quando vários casos estão disponíveis, é correto assumir que o<- done
será escolhido eventualmente , mas não é necessário que seja escolhido imediatamente assim que for fechado. Claro, essa dúvida é quando ambos os casos, ie<-done
e<-c
estavam disponíveis.Existe uma possibilidade que
<- v
não está escritavalStream
quandodone
é fechada e é perdida para sempre, correto?
orDone := func(done, c <-chan interface{}) <-chan interface{} {
valStream := make(chan interface{})
go func() {
defer close(valStream)
for {
select { //2
case <-done:
return
case v, ok := <-c:
if ok == false {
return
}
select {
case valStream <- v: //3
case <-done: //1
}
}
}
}()
return valStream
}
Basicamente, corrija-me se eu estiver errado ou confirme que meu entendimento da execução está correto. De fato, há "brechas" no código e isso é apenas comportamento do canal aqui.
Pergunta semelhante aqui
<-done
também deve ter um retorno. Este código está contando com a seleção externa para capturar<-done
, o que pode não acontecer imediatamente<-done
estiver disponível, será escolhido eventualmente. É provável que seja escolhido rapidamente, mas você está certo. Não há garantia de que, mesmo que o select interno escolha<-done
, o externo também o escolherá em sua próxima iteração.<-done
estiver disponível, então sim, há uma possibilidade de quev
seja lido, mas não escrito