Go Channel Chan__go

Source: Internet
Author: User

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 blocksat 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!") }
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.