Go language programming-Chapter 8--goroutine and channel

Go Language Programming-Chapter 8 – Goroutines and Channels

8.1 goroutine

When the program starts, there is only one goroutine to call the main function, called the main goroutine. New goroutine needs to be created through the go statement. Add the go keyword before ordinary function or method calls.

f() // 调用f
go f() // 新建一个调用 f() 的 goroutine,不用等待。

8.4 Channel

Goroutine is the concurrent execution body of the Go program, and the channel is the connection between them. A channel is a communication mechanism that allows one goroutine to send specific values ​​to another goroutine. Each channel is a conduit of a specific type, called the channel's element type. A channel with elements of type int is written as chan int.

Use the built-in make function to create a channel:

ch := make(chan int)

The zero value of a channel is nil. Channels of the same type can be compared using the == symbol.

Channels have two main operations: sending and receiving, both of which are collectively called communication.

ch <- x // 发送语句
x = <- ch //赋值语句中的接收表达式

The channel supports close, usage close(ch). If the send operation is performed after close, it will cause downtime. If a read operation is performed on a closed channel, all values ​​that have been sent will be obtained until the channel is empty; at this time, any receive operations will be completed immediately, and a zero value corresponding to the channel element type will be obtained.

Creating a channel accepts an optional second parameter, an integer representing the channel capacity. like

ch = make(chan int) // 无缓冲通道
ch = make(chan int, 0) // 无缓冲通道
ch = make(chan int, 3) // 容量为 3 的缓冲通道

8.4.1 Unbuffered channels

Send operations on unbuffered channels will block until another goroutine performs a receive operation on the corresponding channel, at which time the value transfer is completed and both goroutines can continue execution. Conversely, if the receive operation is performed first, the receiving goroutine will block until another goroutine sends a value on the same channel.

8.4.2 Pipes

Channels can be used to connect goroutines so that the output of one is the input of another. This is called a pipeline.

At the end, it is not necessary to close each channel. A channel can be reclaimed by the garbage collector based on whether it is accessible or not. Attempting to close an already closed channel will cause downtime.

8.4.3 One-way channel type

package main

import "fmt"

//!+
func counter(out chan<- int) {
    
    
	for x := 0; x < 100; x++ {
    
    
		out <- x
	}
	close(out)
}

func squarer(out chan<- int, in <-chan int) {
    
    
	for v := range in {
    
    
		out <- v * v
	}
	close(out)
}

func printer(in <-chan int) {
    
    
	for v := range in {
    
    
		fmt.Println(v)
	}
}

func main() {
    
    
	naturals := make(chan int)
	squares := make(chan int)

	go counter(naturals)
	go squarer(squares, naturals)
	printer(squares)
}

8.4.4 Buffer channel

If there is no buffering channel, when the sending goroutine sends data to the channel, if there is no goroutine to receive it, this situation is called goroutine leakage. Unlike recycling variables, leaked goroutines are not automatically recycled.

8.7 Using select multiplexing

select {
    
    
	case <- ch1
		// 
	case x <- ch2
	// 
	case ch3 <- y :
    //
    default
}

select is like a switch statement in that it has a series of cases and an optional default branch. Each situation specifies a communication and an associated piece of code.
select waits until a communication tells it that something can be executed. If multiple conditions are met at the same time, select randomly selects one, thus ensuring that each channel has the same chance of being selected.

Non-blocking channel
The following select will return immediately when executed, regardless of whether there is data in the channel.

select {
    
    
case <- abort:
	fmt.Printf("Launch aborted !\n")
	return
default:
 // 不执行任何操作  
}

8.9 Cancellation

We need a reliable mechanism to broadcast an event on a channel so that many goroutines can think it has happened and then see that it has happened.

When a channel has been closed and all sent values ​​have been read, subsequent read operations return immediately.

var done = make(chan struct{
    
    })

func cancelled() bool {
    
    
	select {
    
    
		case <- done:
			return true
		default:
			return false
	}
}

go func() {
    
    
	os.Stdin.Read(make([]byte, 1))
	close(done)
}()

Guess you like

Origin blog.csdn.net/houzhizhen/article/details/135438074