This is a creation in Article, where the information may have evolved or changed.
The guy who wrote go should have heard the words of Rob Pike.
Do not communicate by sharing memory; Instead, share memory bycommunicating.
I believe that many friends and I, in the actual application of the total sense of no benefit, in order to use the channel. But in my experience, this is the code when the scene is not complicated, the channel is not familiar with the result, so I hope this article can bring you a new idea, the Golang elegant channel has a deeper understanding:
Fan In/out
The output of the data sometimes needs to be fan-out/In (Fanin/out), but in the function calls often have to modify the interface, and the upstream and downstream of the data is very dependent on the very high, so the general use of channel Fanin/out, so you can easily achieve similar to the shell of the pipeline.
func fanIn(input1, input2 <-chan string) <-chan string { c := make(chan string) go func() { for { select { case s := <-input1: c <- s case s := <-input2: c <- s } } }() return c}
Sync Goroutine
Two goroutine synchronization states, such as a goroutine need to let B goroutine exit, the general practice is as follows:
func main() { g = make(chan int) quit = make(chan bool) go B() for i := 0; i < 3; i++ { g <- i } quit <- true // 没办法等待B的退出只能Sleep fmt.Println("Main quit")}func B() { for { select { case i := <-g: fmt.Println(i + 1) case <-quit: fmt.Println("B quit") return } }}/*Output:123Main quit*/
But the main function is not able to wait for B to exit properly, so B quit no way to print, the program directly exited. However, Chan is the first object in go, so you can pass Chan into Chan, so the above code can define quit as Chan Chanbool, which controls the synchronization of two Goroutine
func main() { g = make(chan int) quit = make(chan chan bool) go B() for i := 0; i < 5; i++ { g <- i } wait := make(chan bool) quit <- wait <-wait //这样就可以等待B的退出了 fmt.Println("Main Quit")}func B() { for { select { case i := <-g: fmt.Println(i + 1) case c := <-quit: c <- true fmt.Println("B Quit") return } }}/* Output123B QuitMain Quit*/
Distributed recursive invocation
In real life, what would you do if you wanted to talk to the President of the United States? The first step is to call your friends in the United States, and then they will start their own networks, find people who might know the President of the United States, and so on until they find it. This is also the same in the Kadmelia distributed system, if you need to get the target ID information, then keep querying, the query node even if there is no relevant information, it will return to the nearest node, until the ID or wait for the timeout. Well, how do you do this with go?
Func Recursivecall (CTX context. Context, id []byte, initialnodes []*node] {seen: = map[string]*node{}///Seen node record request: = Make (chan *node, 3)//Set Request node channel//Input initial node go func () {for _, N: = range Initialnodes {request <-n} } () Out:for {//loop until the data is found if the DataSource = nil {return}//In the new request, timeout and on Layer Cancel request in select Select {case N: = <-request:go func () {//Send new please Request Response: = S.sendquery (CTX, N, methodfindvalue, id) Select {case <-ctx . Done (): Case msg: =<-response:seen[responsetonode (response)] = N//More Newly seen node information//Load new node for _, RN: = Range Loadnodeinfof Rombyte (Msg[payloadstart:]) {mu. Lock () _, OK: = Seen[rn. HexID ()] Mu. Unlock ()//have seen, skip this node if OK { Continue} AddNode (RN) The new node is fed into channel request <-RN} }}} () Case <-time. After ($ * time.millisecond): Break out//break to outer layer, otherwise just jump to the outside of the loop case <-ctx. Done (): Break Out}} return}
At this point the Bufferedchannel is similar to a local queue, processing the required nodes, but the subtlety of this code is that the block operation here is select and can be canceled at any time, rather than waiting or knowing the length of the queue.
What questions do you have about the use of these three channel types, welcome to discuss ╮(╯▽╰)╭