The CSP model is used in the Go language for thread communication. To be precise, it is communication between lightweight thread goroutines. The CSP model is similar to the Actor model. It is also composed of independent entities that execute concurrently. The entities also communicate by sending messages.
1. The difference between the Actor model and the CSP model:
Actors communicate directly, while CSP communicates through Channel. In terms of coupling degree, the two are the same. There is a difference, the latter is more loosely coupled.
The main difference is that in the CSP model, the sender and receiver of the message are loosely coupled through Channel. The sender does not know which receiver has consumed his message, and the receiver does not know which sender sent the message. . In the Actor model, since the Actor can choose which incoming message to process based on its own state, autonomy and controllability are better.
In order not to block the process in the Go language, the programmer must check different incoming messages in order to foresee and ensure the correct order. The advantage of CSP is that Channel does not need to buffer messages, while Actor theoretically needs an unlimited size mailbox as message buffer.
The message sender of the CSP model can only send a message when the receiver is ready to receive the message. In contrast, message passing in the Actor model is asynchronous, that is, the sending and receiving of messages do not need to occur at the same time, and the sender can send the message before the receiver is ready to receive the message.
2. Detailed explanation of Go Channel
The definition format of Channel type is as follows:
ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
It includes the definition of three types. The optional <- represents the direction of the channel. If no direction is specified, the Channel is bidirectional and can both receive data and send data.
chan T // 可以接收和发送类型为 T 的数据 chan<- float64 // 只可以用来发送 float64 类型的数据 <-chan int // 只可以用来接收 int 类型的数据
<-Always combine with the leftmost type first. (The <- operator associates with the leftmost chan possible)
c := make(chan bool) //创建一个无缓冲的bool型Channel c <- x //向一个Channel发送一个值 <- c //从一个Channel中接收一个值 x = <- c //从Channel c接收一个值并将其存储到x中 x, ok = <- c //从Channel接收一个值,如果channel关闭了或没有数据,那么ok将被置为false
By default, the channel sender and receiver will block until the other party is ready to send or receive, which makes the Go language without locking or Other conditions naturally support concurrency.
Use make to initialize the Channel, and you can set the capacity:
make(chan int, 100) #//创建一个有缓冲的int型Channel
Capacity (capacity) represents the maximum number of elements that the Channel can accommodate, and represents the size of the Channel's cache.
If the capacity is not set, or the capacity is set to 0, it means that the Channel has no cache.
You can receive/send data from/to a channel in multiple goroutines without having to consider additional synchronization measures.
Channel can be used as a first-in-first-out (FIFO) queue, and the order of received data and sent data is consistent.
Channel without buffering has both communication and synchronization characteristics, and is very popular in concurrent development.
// _Channels_ are the pipes that connect concurrent // goroutines. You can send values into channels from one // goroutine and receive those values into another // goroutine. package main import "fmt" func main() { // Create a new channel with `make(chan val-type)`. // Channels are typed by the values they convey. messages := make(chan string) // _Send_ a value into a channel using the `channel <-` // syntax. Here we send `"ping"` to the `messages` // channel we made above, from a new goroutine. go func() { messages <- "ping" }() // The `<-channel` syntax _receives_ a value from the // channel. Here we'll receive the `"ping"` message // we sent above and print it out. msg := <-messages fmt.Println(msg) }
Here we create an unbuffered string type Channel, and then pass "ping" to this Channel using channel<- in a goroutine. <-The channel receives this value and prints it out in the main function. In fact, here we use Channel to quietly transfer the "ping" message from a goroutine to the main goroutine, realizing communication between threads (to be precise, between goroutines).
Because the channel sender and receiver will block until the other party is ready to send or receive, this allows us to wait for the "ping" message at the end of the program without the need for other synchronization operations.
Let’s look at another example: After the user-defined goroutine completes an operation, it reminds the main goroutine:
// We can use channels to synchronize execution// across goroutines. Here's an example of using a// blocking receive to wait for a goroutine to finish.package mainimport "fmt"import "time"// This is the function we'll run in a goroutine. The// `done` channel will be used to notify another// goroutine that this function's work is done.func worker(done chan bool) { fmt.Print("working...") time.Sleep(time.Second) fmt.Println("done") // Send a value to notify that we're done. done <- true}func main() { // Start a worker goroutine, giving it the channel to // notify on. done := make(chan bool, 1) go worker(done) // Block until we receive a notification from the // worker on the channel. <-done }
The CSP model is used in the Go language for thread communication. To be precise, it is communication between lightweight thread goroutines. The CSP model is similar to the Actor model. It is also composed of independent entities that execute concurrently. The entities also communicate by sending messages.
【Recommended course: Go video tutorial】
The above is the detailed content of Channel related explanations in Go language. For more information, please follow other related articles on the PHP Chinese website!