I spent several hours to figure out some conceptions about channel tonight
1. buffered channel and non-buffered Channel
Buffered Channel
bufferedchan := make(chan int, 1)
When adding element into bufferedchan, it will not blocked if it is not full.
For example:
package mainimport "fmt"func main() { messages := make(chan string, 1) messages <- "buffered" fmt.Println("quit!")}
The program won't block and the answer is:
Quit!
2. Channel is thread safe,
package mainimport "fmt"func main() { jobs := make(chan int, 5) done := make(chan bool) go func() { ------------------------------- (Part I) fmt.Println("enter go routinue") for { j, more := <-jobs if more { fmt.Println("received job", j) } else { fmt.Println("received all jobs") done <- true return } } }() jobs <- 1 ------------------------------- (part II) jobs <- 2 jobs <- 3 close(jobs) fmt.Println("sent all jobs and closed")
<-done ------------------------------- (Part III)}
The result is:
Sent all jobs and closed
Enter go routinue
Received job 1
Received job 2
Received job 3
Received all jobs
Firstly, it executes (Part II) and stop at <-done.
And then a child routinue executes (part I) and done <-true.
Now the channel done is actived and continue to execute.
* If the channel jobs is not closed in main, the statement "J, more: = <-jobs" in (Part I) will block. The deadlock will happen.
* If we don't set "<-done" in main, main will not wait the child routinue to finish.
Go channel Learning