2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Goroutines run in the same address space, so access to shared memory must be synchronized.Goroutines communicate to share memory, rather than sharing memory to communicate.
The reference type channel is a specific implementation of the CSP mode and is used for multiple goroutine communications. It implements synchronization internally to ensure concurrency safety.
Similar to a map, a channel is also a reference to the underlying data structure created by make.
When we copy a channel or use it as a function parameter, we just copy a channel reference, so the caller and the callee will reference the same channel object. Like other reference types, the zero value of the channel is nil.
When defining a channel, you also need to define the type of values that will be sent to the channel. Channels can be created using the built-in make() function:
make (chan Type)
make (chan Type,capacity)
channel<-value //发送value 到channel
<-channel //接收并将其丢弃
x:=<-channel //从 channel 中接收数据,并賦偵给x
x,ok:=<-channel //功能同上,同时检查通道是否已关闭或者是否为空
By default, channel sends and receives are blocked unless the other end is ready, which makes goroutine synchronization much simpler without explicit locks.
An unbuffered channel is a channel that has no ability to store any value before receiving it.
This type of channel requires that the sending goroutine and the receiving goroutine are ready at the same time to complete the sending and receiving operations. If the two goroutines are not ready at the same time, the channel will cause the goroutine that performs the sending or receiving operation first to block and wait.
This interactive behavior of sending and receiving on the channel is inherently synchronous. Neither operation can exist independently of the other.
The following diagram shows how two goroutines can share a value using unbuffered channels:
make (chan Type)//等价于make (chan Type,0)
If no buffer capacity is specified then the channel is synchronous and will therefore block until the sender is ready to send and the receiver is ready to receive.
A buffered channel is a channel that can store one or more values before receiving them.
This type of channel does not require that the goroutines must complete sending and receiving at the same time. The conditions under which the channel blocks sending and receiving actions are also different. Receiving actions will only block if there are no values to receive in the channel. Sending actions will only block if the channel has no available buffer to accommodate the value to be sent.
This leads to a big difference between buffered and unbuffered channels: unbuffered channels guarantee that the sending and receiving goroutines will exchange data at the same time: buffered channels have no such guarantee.
make (chan Type,capacity)
If a buffer capacity is given, the channel is asynchronous and communication proceeds without blocking as long as the buffer has free space to send data or contains data that can be received.
The channel can use ok to detect whether the channel is still open. If the channel is closed, no data will be read.
num ,ok:=<-ch
Can detect if the channel is closed.By default, channels are dual-access, that is, data can be sent to them as well as received from them.
However, we often see a channel passed as a parameter and the value is expected to be used unidirectionally, either to send data or to receive data. In this case, we can specify the direction of the channel. The declaration of a unidirectional chamel variable is very simple, as follows:
var ch1 chan int //ch1双向
var ch2 chan<-float64 //ch2单向,只能用于写float64数据
var ch3 <-chan int //ch3单向,只能用于读int数据
chan<- means that data enters the pipeline. To write data into the pipeline, it is output to the caller.
<-chan means data comes out of the pipe. For the caller, it gets the data from the pipe, which is of course input.
A channel can be implicitly converted to a one-way queue, which only receives or sends data. A one-way channel cannot be converted to a normal channel.