Go channel Channel

Nobumichi (Channel)

Channel (Channel) may be considered a communication conduit between the coroutine. Data may be transmitted from one end of the channel and received at the other end.

The default sync mode is required to send and receive pairs. Otherwise it will be blocked until another channel is ready after wake-up.

Unbuffered channels into channels and channel buffer
unbuffered channels: synchronization channel is not received before the ability to store any value. This type of channel only send and receive at the same time ready to operate next channel, otherwise it will lead to blocking.
Buffer channel: the channel is asynchronous, when an opened can be created to store one or more values of the channels. This type does not require simultaneous transmission and reception. As long as there is unused space in the buffer used to send data, or further comprising data may be received, then the communication will be performed without blocking.

Send and receive default blocking (synchronous). What does it mean? When the data is transmitted to the channel, the program control will occur at the statement transmission data block until some other coroutine Go to read data from the channel, will be unblocked.
Similarly, when reading the data channel, if no other coroutine write data into this channel, then the read process will always blocked.
Such characteristics of the channel can support efficient communication between Go coroutine, no need to use an explicit condition variables locks or other common programming languages.

Channel statement

var ch chan T

We declare the name of a type called T ch channel
channel 0 is nil. We need to create a channel through the built-in functions make, just create map and slice the same.

Unbuffered channel

ch := make(chan T)

Channel buffer

ch := make(chan T,cap)

Create (1) channel

     // built-in type channel
    var a chan int
    if a == nil {
        a = make(chan int)
        fmt.Printf("%T\n", a) //chan int
    }
    // custom type channel
    where p chan person
    if p == nil {
        p = make(chan person) //chan main.person
        fmt.Printf("%T\n", p)
    }

(2) send and receive data over the channel

Note: The default is to send and receive blocked

data: = <- a // read from a data channel and the read value is assigned to the variable data.
a <- data // write the data to a channel.
package main
import (
    "fmt"
    "time"
)
func hello(done chan bool) {
    fmt.Println("hello go routine is going to sleep")
    time.Sleep(4 * time.Second)
    // only after writing data to continue
    done <- true
    fmt.Println("hello go routine awake and going to write to done")
}
func main() {
    done := make(chan bool)
    go hello(done)
    <-done
    fmt.Println("Main received data")
}

(4) deadlock

When Go coroutine to a data transmission channel, there will be reasonable to say that other coroutine Go to receive data. If not, the program will trigger panic at run time, the formation of a deadlock.

Similarly, when there is more coroutine Go to receive data from a channel, we expect another coroutine will Go To write data channel, or else the program will trigger panic.

package main

func main() {  
    ch := make(chan int)
    ch <- 5
}

(5) with a unidirectional channel bidirectional channel

Bidirectional channel: i.e. both transmitting data over a channel, and can receive data.
Unidirectional channel: a channel can only send or receive data.

Unidirectional channel:

package main

import "fmt"

func sendData(sendch chan<- int) {  
    sendch <- 10
}

func main() {  
    sendch := make(chan<- int)    
    go sendData(sendch)
    fmt.Println(<-sendch)
}

chan <- int-only transport channel is defined as an arrow pointing chan. We tried in the main function to receive data through the only transmission channel, so the compiler error:
invalid Operation: <-sendch (receive from the send-only of the type chan <- int)
everything is going well, but can not read a data CD What transmitting channel what is it?
That's where conversion channel (Channel Conversion) a. Converting a bidirectional channel to transport channel CD or CD yield (Receive Only) channel are feasible, but the reverse is not.

package main

import "fmt"

func sendData(sendch chan<- int) {  
    sendch <- 10
}
func main() {  
    cha1 := make(chan int)    
    go sendData(cha1)
    fmt.Println(<-cha1)
}

We have created a two-way channel cha1. cha1 passed as a parameter to the sendData coroutine. Lane sendData function parameters sendch chan <- int cha1 the CD is converted to a transmission channel.
Whereupon the channel is in a coroutine sendData CD transport channel, while the main coroutine where Go is a bidirectional channel. The program prints the final output 10.

(6) Close Channel

The data sender can close the channel, inform the receiver that no channel data is sent.

When data is received from a channel, the recipient can use a multi-variable to check whether a channel has been closed.

v, ok: = <- ch
above statement, if a data channel transmitted successfully received, then the ok equal to true. And if ok equal false, that we try to read a closed channel.
Read from the closed to the channel value is zero value of the channel type. For example, when the channel is a channel of type int, the value is read from a closed channel will be zero.

package main

import (  
    "fmt"
)

func producer(chnl chan int) {  
    for i := 0; i < 10; i++ {
        chnl <- i
    }    close(chnl)
}

func main() {  
    ch := make(chan int)    
    go producer(ch)    
    for {
        in, ok = <CH        
        if ok == false {            
            break
        }
        fmt.Println("Received ", v, ok)
    }
}

In the above procedure, producer coroutine from 0 to 9 will write channel chn1, and then close the channel.
We have a main function for an infinite loop, checking whether the variable ok channel has been closed. If ok equals false, described channel has been closed, then exits the for loop.
If ok equal to true, the value of the received print out the value is ok.

(7) traversing the channel

Channel support range for traversal

package main

import (
    "fmt"
    "time"
)

func producer(chnl chan int) {
    defer close (chnl) // end program execution closed channel
    for i := 0; i < 10; i++ {
        time.Sleep (300 * time.Millisecond) // one second write once
        chnl <- i // write
    }
}
func main() {
    ch := make(chan int)
    go producer(ch)
    // ch received data channel until the channel is closed.
    for v := range ch {
        fmt.Println (in)
    }
} 

It may be custom channel for loop iterates

for {
        v, ok: = <-ch // read
        fmt.Println (in, ok)
        if ok == false {// when data can not be read out of the cycle
            break
        }
    }

 

Guess you like

Origin www.cnblogs.com/-wenli/p/11817266.html