Channel in Go language (Let's Go twenty-nine)

Continuing from the previous article, if you want to communicate between goroutines, you need to pass messages through the Channel channel.

Channel is an intra-process communication method, so the process of passing objects through channels is consistent with the behavior of parameter passing when calling functions, for example, pointers can also be passed. If cross-process communication is required, we recommend using a distributed system method to solve it, such as using communication protocols such as Socket or HTTP. The Go language also has very complete support for the network.

Channel is type-dependent, that is, a Channel can only pass one type of value, and this type needs to be specified when declaring the Channel. If you know something about Unix pipes, it's not difficult to understand Channel, which can be thought of as a type-safe pipe.

var chanVar chan chanType  // 声明 信道  chanVar 信道变量  chanType  信道类型
chanVar = make(chan chanType) //声明后的 信道 须通过 make() 函数进行创建

channel to send data

Use <-operators to send data.

chanVar <- value  //chanVar 信道变量  value 发送的数据

Note: The data type to be sent must be consistent with the type of the channel variable.

channel to receive data

Channels accepting data also use <-operators.

There are four ways to receive data.

  • 1. Blocking mode to receive data
data := <-chanVar

When this statement is executed, it will block until data is received and assigned to the data variable.

  • 2. Non-blocking receiving data
data, ok := <-chanVar

data: Indicates the received data. When no data is received, data is zero for the channel type.

ok: Indicates whether the data is received.

The non-blocking channel receive method can cause high CPU usage, so it is used very rarely. If you need to implement receiving timeout detection, you can cooperate with select and timer channel, which will be mentioned later.

  • 3. Receive any data, ignore the received data
<-chanVar

After blocking on receiving data, ignore the data returned from the channel.

Execution of this statement will block until data is received, but received data will be ignored. This method actually only achieves concurrent synchronization by blocking sending and receiving between goroutines through channels.

package main

import (
	"fmt"
)

func main() {
    
    

	chanVar := make(chan string)

	go func() {
    
    
		fmt.Println(" start goroutine")
		chanVar <- "https://qiucode.cn"
		fmt.Println("end goroutine")
	}()

	fmt.Println("out print start")
	<-chanVar
	fmt.Println("out print end")

}

insert image description here

The code description is as follows:

  • Line 9, constructs a channel for synchronization.
  • Line 11 starts the concurrency of an anonymous function.
  • Line 13, when the anonymous goroutine is about to end, notify the main goroutine through the channel, this sentence will be blocked until the main goroutine receives it.
  • Line 18, after starting the goroutine, immediately wait for the anonymous goroutine to end through the channel.
  • 4. Loop reception

The data reception of the channel can use the for range statement to perform the reception operation of multiple elements.

for data := range chanVar {
    
    
    
}

The channel chanVar can be traversed, and the result of the traverse is the received data. The data type is the data type of the channel. There is only one variable obtained through for traversal, that is, data in the above example.

package main

import (
	"fmt"
)

func main() {
    
    

	chanVar := make(chan int)

	go func() {
    
    
		for i := 0; i < 5; i++ {
    
    
			chanVar <- i
		}
	}()

	for data := range chanVar {
    
    
		fmt.Println(data)
		if data == 4 {
    
    
			break
		}
	}

}

insert image description here

When the value 4 is received, stop receiving. If you continue to send, because the receiving goroutine has exited, no goroutine will send to the channel, so the runtime will trigger a crash and report an error.

Guess you like

Origin blog.csdn.net/coco2d_x2014/article/details/127560438