Chan used for communication between Goroutine 1, the base has a buffer channel and no buffer channel
No buffer channel: make (chan int)
Buffer channel: Make (chan int, 5) No buffer channel will cause goroutine synchronization of send and receive
Mainly reflected in the following two points:
-No buffer channel will cause the sending goroutine to block until the corresponding Chan has a receiver
Package main
Import (
"FMT"
"Time"
)
var ch chan int
func main () {
var i int = 9
ch = make (chan int)
Go Waiting ()
FMT. Println ("Send To Chan, Time:", Times.) Now ())
ch <-i
fmt. PRINTLN ("Send Complete, Time:", Times.) Now ())
//ch <-i time
. Sleep (10000000000)
}
func Waiting () {for
{time
. Sleep (10000000000)//Receive coprocessor wait 10 seconds
I, OK: = <-ch
if!ok {
fmt. Println ("Chan is close!")
Break
}
FMT. Println ("recv:", i)
}
fmt. Println ("Waiting end!")
}
Output:
Winterdemacbook-pro:chantest winter$./chantest1
sent to Chan, time: 2017-12-07 16:12:04.856740287 +0800 CST
Recv:9
send completed, time: 2017-12-07 16:12:14.857350085 +0800 CST
winterdemacbook-pro:chantest winter$
Similarly, no buffer channel will cause the receiving goroutine to block until the corresponding Chan has sent
Package main
Import (
"FMT"
"Time"
)
var ch chan int
func main () {
var i int = 9
ch = make ( Chan int) go
waiting ()
FMT. Println ("Send To Chan, Time:", Times.) Now ()) Time
. Sleep (10000000000)//wait 10 seconds to send data to chan
ch <-i
fmt. PRINTLN ("Send Complete, Time:", Times.) Now ())
//ch <-i time
. Sleep (10000000000)
}
func Waiting () {for
{
//time. Sleep (10000000000)//Receive coprocessor wait 10 seconds
FMT. PRINTLN ("Begin to receive data from Chan, Time:"). Now ())
I, OK: = <-ch
fmt. Println ("There's data in Chan, Time:"). Now ())
if!ok {
fmt. Println ("Chan is close!")
Break
}
FMT. Println ("recv:", i)
}
fmt. Println ("Waiting end!")
}
Output:
Winterdemacbook-pro:chantest winter$./chantest1
sent to Chan, time: 2017-12-07 16:17:35.598050582 +0800 CST
Start receiving data from Chan, Time: 2017-12-07 16:17:35.598060998 +0800 CST
sent over, time: 2017-12-07 16:17:45.602548482 +0800 CST
Chan has data, time: 2017-12-07 16:17:45.602599793 +0800 CST
Recv:9
began to receive data from Chan, Time: 2017-12-07 16:17:45.602665344 + 0800 CST
buffer channel, quite with a queue, the maximum length of the queue is specified at creation timeAn empty Chan will cause the receiving goroutine to block a full Chan, causing the send goroutine to block
2, will cause the program to hang out of the exception
send and receive of nil channel
Chan's 0 value is nil, not initialized equal to nil
Package main
Import (
"FMT"
)
func main () {
var ch chan int
if ch = = Nil {
FMT. PRINTLN (' ch is nil ')
}
}
Output:
Winterdemacbook-pro:chantest winter$./chantest1
Ch is nil
The nil value of the Chan on the send and receive will cause the program to hang out and prompt "nil Chan"
Package main
Import (
"FMT"
)
var ch chan int
func main () {
var i int = 9 go
waiting ()
Ch & lt;-i
}
func Waiting () {
i:= <-ch
fmt. Println ("recv:", i)
}
Output:
Winterdemacbook-pro:chantest winter$./chantest1
fatal Error:all
Goroutines are asleep-deadlock! Goroutine 1 [Chan Send (Nil Chan)]:
main.main ()
/users/winter/code/go_project/src/test/chantest/ Chantest1.go:10 +0x64
goroutine 5 [Chan receive (Nil Chan)]:
main.waiting ()
/users/winter/code/go_ Project/src/test/chantest/chantest1.go:15 +0x50
created by Main.main
/users/winter/code/go_project/src/ Test/chantest/chantest1.go:9 +0x35
send to a channel without a recipient
Send data to a channel without the recipient, and the program hangs, prompting "deadlock"
Package main
Import (
"FMT"
)
var ch chan int
func main () {
var i int = 9
ch = make (chan int)
//ch No recipient
ch <-i
}
func Waiting () {
i:= <-ch fmt
. Println ("recv:", i)
}
Output:
Winterdemacbook-pro:chantest winter$./chantest1
fatal Error:all
Goroutines are asleep-deadlock! Goroutine 1 [chan send]:
main.main ()
/users/winter/code/go_project/src/test/chantest/chantest1.go:11 + 0x7f
closing (close) action after Chan
a receive operation on a closed Chan will fetch all the values that have been sent until the Chan is empty, then the blocking is lifted, and the 0 value corresponding to the Chan element type is obtained. That reads data from a closed Chan and never blocks。
at the receiver you can tell if Chan is off, but there is no way to tell if Chan is off at the sender, so you can only close the Chan at the sender end.。
closing Chan is necessary because GC recycling Chan is not based on whether Chan is closed, but on whether it is accessible.
In General, do not close Chan because closing a Chan has the following risks:
Closing a closed Chan will cause the program to crash
Closing a 0-value Chan can cause the program to crash
After Chan closes, the send operation causes the program to crash
Package main
Import (
"FMT"
"Time"
)
var ch chan int
func main () {
var i int = 9
ch = make ( Chan int) go
waiting ()
ch <-i close
(CH)
ch <-i time
. Sleep (10000000000)
}
func Waiting () {for
{
i:= <-ch fmt
. Println ("recv:", i)
}
}
Output:
Winterdemacbook-pro:chantest winter$./chantest1
recv:9
recv:0
recv:0
recv:0
recv:0
recv:0
recv:0
panic:send on closed channel
Goroutine 1 [running]:
main.main ()
/users /winter/code/go_project/src/test/chantest/chantest1.go:14 +0xda
Visible, the received goroutine receives the last element and gets the 0 value of the Int. Until the main goroutine to the closing of the Chan send cause the program to hang up.
So how do you know if a Chan has been close? reading data from Chan is generally written as I: = <-ch, which actually returns two values, such as I, OK: = <-ch, the first return value represents the acquired element, and the second return value is a bool type, equals false to read exceptions. So you can tell if Chan is close by this return value.
package main import ("FMT" "Time") var ch chan int func main () {var i int = 9 ch = make (chan int) go Waiting () ch <-i close (CH)//ch <-i time. Sleep (10000000000)} func Waiting () {for {i, OK: = <-ch if!ok {fmt.
Println ("Chan is Close!") Break} FMT. Println ("recv:", i)} fmt.
Println ("Waiting end!") }