This is a creation in Article, where the information may have evolved or changed.
The real scenario is that when you test the order of the receipts, you add a tick and you find the packet dropped.
So let's take a look at an application example:
Package Mainimport ("FMT" "Runtime" " Time") Func init () {runtime. Gomaxprocs (runtime. NUMCPU ())}func main () {ch:= Make (chanint,1024x768) go func (Ch Chanint) { for{val:= <-ch FMT. Printf ("val:%d\n", Val)} } (CH) tick:= time. Newticker (1*Time . Second) forI: =0; I < -; i++ { Select { CaseCH <-I: Case<-tick. C:fmt. Printf ("%d:case <-tick. c\n", I)} Time. Sleep ( $*Time.millisecond)} close (ch) tick. Stop ()}
The output results are as follows:
Val:0val:1val:2val:3val:4val:56:case <-tick. Cval:7val:8val:910:case <-tick. Cval:11val:12val:13val:1415:case <-tick. Cval:16val:17val:18val:19
The problem is in this select:
Select { case ch <- I: case <- tick. C: FMT. Printf ("%d:case <-tick. c\n", i)}
[Tick. C description] When the two case conditions are met, the runtime system will use a pseudo-random algorithm to determine which case will be executed. So when tick. C the condition satisfies the loop, there is some probability that the ch<-i is not sent (although the channel ends are not blocked, satisfies the sending condition)
Solution 1: once tick. C Random case is randomly executed, ch<-i (not respectable, if more than one is not universal)
Select { case ch <- I: case <- tick. C: FMT. Printf ("%d:case <-tick. c\n", i) <- i}
Solution 2: put the tick. C's case is placed in a single select and added a default (guaranteed not to block)
Select { case ch <- I:}Select { case <- tick. C: FMT. Printf ("%d:case <-tick. c\n", i) default:}
The output of both solutions is the desired result:
Val0Val:1Val:2Val:3Val:45: Case<-tick. Cval:5Val:6Val:7Val:8Val:9Ten: Case<-tick. Cval:TenVal: OneVal: AVal: -Val: - the: Case<-tick. Cval: theVal: -Val: -Val: -Val: +