If goroutine is the Go language , then concurrent body of the program, then the channels is the communication mechanism between them. Communication channels is a mechanism that allows a goroutine by sending it to another goroutine value information. Each channel has a special type, i.e. the type of data channels can be transmitted. Int type can transmit a data channel is generally written as chan int.
Go language instead of promoting the use of shared memory communication method, when a resource needs to be shared among goroutine, goroutine channel set up between a pipe, and provides a synchronization mechanism to ensure the exchange of data. When you declare a channel, you need to specify the type of data to be shared. Channel can be shared by the built-in type, the type name, the type and structure of a reference value or a pointer type.
The method here is to use the communication channel (channel), as shown below.
Characteristics channel
Go language channel (channel) is a special type. At any time, only one of them goroutine access channel to send and retrieve data. between goroutine can communicate through the channel.
A conveyor belt or like channel queue, always follow the FIFO (First In First Out) rules guarantee the order of the data transceiver.
Channel type declaration
Channel itself needs a type of modification, you need to identify the type of slice like the element type. Channel element type is the type of data transmitted therein, the following statement:
var channel chan variable channel type
- Channel Type: the type of data in the channel.
- Channel variables: Save the variable channel.
Null chan type is nil, in order to make use of the need to meet after the statement.
Create a channel
Channel is a reference type, you need to make use of to create, in the following format:
Channel instance: = make (chan data type)
- Data type: type of element within the transmission channel.
- Channel Example: channel handle created by make.
Consider the following example:
ch1: = make (chan int) // Create an integer type of channel ch2: = make (chan interface { }) // Create an empty channel interface type, can be stored in any format type Equip struct {/ * * some fields /} CH2: = the make (Chan Equip *) Equip // Create a pointer type channels can be stored Equip *
Transmitting data using channel
After the channel is created, you can use the channel for transmit and receive operations.
Format 1) channel for transmitting data
Transmission channel using a special operator <-
, the data format is transmitted through the channel:
Variable Channel <- Value
- Channel variables: create a good channel instance by make.
- Found: it can be a variable, a constant, expression or function return values. It must match the type of the value ch channel element type.
2) Examples of the data transmitted through the channel
After creating a channel used make, it can be used <-
to send data to the channel, as follows:
main Package FUNC main () { // create a integer channel CH: = the make (Chan int) // attempt to transmit through the channel 0 CH <- 0 }
operation result:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send]: main.main() D:/example.v2/src/study/main.go:7 +0x57 Error: process exited with code 2.
Error means: find running all goroutine (including main) are in a wait goroutine. That is all goroutine channel is not formed in the transmission and reception of the corresponding code.
Reception data using channel
Channel receiver use the same <-
operator, the receiving channel has the following features:
a transceiver channel ① operation performed between two different goroutine.
Since the data channel in the absence of the receiving side processing, data transmission side will continue to clog, so the channel must be received in another of goroutine.
② will continue to block until receiving the transmitter sends data.
If the recipient receives the channel data is not sent by the sender, the recipient block will also occur until the sender sends data.
③ Each time a receiving element.
Channel can receive only one data element.
Receiving a data channel There are 4 wording.
1) blocking receive data
Blocking mode to receive data, the receive variables as <-
the left the value of the operator, the following format:
data := <-ch
main Package Import ( "FMT" ) FUNC main () { // build a channel CH: = the make (Chan int) // Open a concurrent anonymous function Go FUNC () { fmt.Println ( "Start goroutines") // by the main channel notifying goroutines CH <- 0 fmt.Println ( "Exit goroutines") } () fmt.Println ( "the wait goroutines") // wait anonymous goroutines Data: = <-CH // <- CH fmt.Println ( Data) }
It will be blocked when the statement is executed until the data is received and assigned to the variable data.
2) non-blocking receive data
Use nonblocking when receiving data from the channel, the statement does not occur clogging, the following format:
data, ok := <-ch
- data: indicates that the received data. When data is not received, data of zero value channel type.
- ok: it indicates whether the received data.
main Package Import ( "FMT" ) FUNC main () { // build a channel CH: = the make (Chan int) // Open a concurrent anonymous function Go FUNC () { fmt.Println ( "Start goroutines") // by the main channel notifying goroutines CH <- 0 fmt.Println ( "Exit goroutines") } () fmt.Println ( "the wait goroutines") // wait anonymous goroutines Data, OK: = <-CH IF OK {! fmt.Println ( "NO Data") } the else { fmt.Println (Data) } // Data: = <-CH // <- CH }
The method of receiving channel non-blocking may cause a high CPU occupancy, the use of very small. If you want a receiver timeout detection can be performed with the channel select and timers can be found behind the content.
3) receive any data, the received data is ignored
After blocking receive data ignore the data returned from the channel, in the following format:
<-ch
Blocking will occur when the statement is executed until it receives the data, but the data received will be ignored. This approach is really just goroutine concurrency synchronization between the transceiver by blocking the channel.
main Package Import ( "FMT" ) FUNC main () { // build a channel CH: = the make (Chan int) // Open a concurrent anonymous function Go FUNC () { fmt.Println ( "Start goroutines") // by the main channel notifying goroutines CH <- 0 fmt.Println ( "Exit goroutines") } () fmt.Println ( "the wait goroutines") // wait anonymous goroutines <-CH fmt.Println ( "All DONE") }
4) receives the loop
Receiving data channel can be borrowed for range statement plurality of elements receiving operation, the following format:
for data := range ch { }
main Package Import ( "FMT" "Time" ) FUNC main () { // build a channel CH: = the make (Chan int) // Open a concurrent anonymous function Go FUNC () { // cycle from 3 to 0 for I : =. 3; I> = 0; i-- { // transmission value between 3 and 0 CH <- I // wait during transmission of each time.sleep (time.Second) } } () // iterate receiving channel data for data: Range = CH { // print data channel fmt.Println (data) // when data 0 is encountered, the receive cycle exit iF data == 0 { BREAK } } }
Code as follows:
Generation channel element by an integer make.
The anonymous function concurrently.
Generating a value between 3-0 by cyclic.
The values between 3-0 sequentially transmitted to the channel ch.
1-second pause after every transmission.
Used for receiving data from the channel.
The received data is printed out.
Upon receiving the value 0, the reception is stopped. If you continue to send, because the reception goroutine has quit, goroutine not sent to the channel, and therefore will trigger a run-time error down.