Cache and no-cache interpretation of channel initialization for Golang

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

First of all, when programming the question, the output is different from what I want to expect, later found the Golang community post, one of the posts: Jian elder brother made some explanations.

I extract the key to come:

There is a significant difference between unbuffered and buffered channel, which is that one is synchronous and non-synchronous.

Like what

C1:=make (chan int) unbuffered

C2:=make (Chan int,1) has a cushion

C1<-1

No buffer: not only to C1 Channel 1, but has been to wait for the other Ctrip <-C1 took over this parameter, then c1<-1 will continue, otherwise it has been blocked.

There is buffering: C2<-1 is not blocked, because the buffer size is 1 (actually buffer size is 0), only when the second value, the first one has not been taken away, this time will be blocked.


I do some of the above to explain, it is true to admit that the channel has a cache and no cache is really different, the cache is 1 and does not set the cache output is different. But the above has a cache explanation is reasonable, no cache I reserve the opinion, use the code example to do the analysis.
First Look at example 1:
Package Mainimport ("FMT") func main () {jobs: = make (chan int, 1) did: = Make (chan bool) go func () {//fmt. Println ("Gostart") for I: = 1;; i++ {//fmt. Println ("Goforstart", i) j, more: = <-jobsif more {fmt. Println ("Received job", J)} else {fmt. Println ("Received all jobs") was done <-truereturn}//fmt. Println ("Goforend", I)}} () for j: = 1; J <= 3; J + + {//fmt. Println ("Outfor", j) Jobs <-jfmt. Println ("Sent Job", j)}close (jobs) fmt. PRINTLN ("Sent all Jobs") <-done}

Its output is:
Sent job 1received job 1sent job 2received job 2sent job 3sent all jobsreceived job 3received all jobs
This is a cache situation, the output is the same as everyone expected, each encounter
Jobs <-J
The program will continue to execute down until the program loops to the next jobs <-J, because the open cache of jobs is full, so the program goes to the Goroutine section, in Goroutine, when the program executes to
J, More: = <-jobs
Remove the value from the channel and wait until the Goroutine encounters a block, returning to the external main () function to continue execution
then the analysis looks at Example 2:
The previous program has a cache channel modified to no cache, i.e.:
Jobs: = Make (chan int, 1)
modified to
Jobs: = make (chan int)
and restore all of the comments in the code to execute.
Its output is:
Outfor 1GoStartGoforSTART 1received Job 1GoforEND 1GoforSTART 2sent job 1OutFOR 2sent job 2OutFOR 3received Job 2GoforEND 2GoforSTART 3received Job 3GoforEND 3GoforSTART 4sent job 3sent all jobsreceived all jobs

We analyze: When the For loop runs to the first jobs <-J, the program goes directly to Goroutine, which is verified by the output "Gostart" immediately following "Outfor 1". Then the program executes to the second loop of the for in Goroutine
J, More: = <-jobs
Back to the external main () for loop. But when the external main's for loop executes the second lap, it does not enter goroutine after Jobs <-J, but continues execution, by
Sent Job 2OutFOR 3
Follow
Outfor 2
Be verified. The external for enters the third loop, because the value of jobs has not been removed, so the transfer to goroutine continue to execute.

The problem is
Jobs <-J
whether to continue or block to pass values in other Goroutine, as indicated by the post at the beginning of this article, it should be the jobs channel put J, need Ctrip to take over this parameter, can continue to execute, but the above analysis to see that this is not the case.


Example 3:

Package Mainimport ("FMT") func main () {jobs: = make (chan int) go func () {fmt. Println ("Goroutin Start") for {select {case src: = <-jobs:fmt. Println ("Get", SRC)}}} () for J: = 0; J < 5; J + + {jobs <-jfmt. Println ("Sent Job", j)}close (jobs) fmt. Println ("Finish.")}
Its output is:

Goroutin startget  0Sent job  0Sent job  1Get  1Get  2Sent job  2Sent job  3Get  3Get  4Sent Job  4finish.

When a value is written to the channel, the execution is alternating, that is, random.

The example environment in this article is Go 1.4, which is explained by the fact that Ctrip uses the same CPU to run the output analysis on different time slices.

Goroutine using blocking to synchronize the data between Ctrip is a very important idea, but you should be very careful when you program.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.