「The Go Memory Model」 https://golang.org/ref/mem Summarize the understanding of.
The article above contains three rules for sending and receiving Go channels.
A send on a channel happens before the corresponding receive from that channel completes. (Sending to the channel takes place before the corresponding reception is complete.)
A receive from an unbuffered channel happens before the send on that channel completes. (For unbuffered channels, reception occurs before transmission is complete.)
The kth receive on a channel with capacity C happens before the k+Cth send from that channel completes.
(The kth reception is performed before the k + Cth transmission from the channel with the buffer capacity C is completed.)
And, as a supplement to the above, it is written as follows.
This rule generalizes the previous rule to buffered channels.
(Rule 3 is a generalization of rules 1 and 2)
package main
var a string
func f() {
a = "hello"
}
func main() {
go f()
print(a) //Empty string is output
}
The print output does not wait for the function f to complete.
package main
var c = make(chan int, 10)
var a string
func f() {
a = "hello"
c <- 1 //Any value is acceptable
}
func main() {
go f()
<-c
print(a) //hello and output
}
Since there is a buffer, it is a rule that c <-1
(send) is performed before <-c
(receive). Since hello is assigned to a before sending, it is output as hello.
package main
var c = make(chan int)
var a string
func f() {
a = "hello"
<-c
}
func main() {
go f()
c <- 1 //Any value is acceptable
print(a) //hello and output
}
Since there is no buffer, the output <-c
is done before the input c <-1
.
Japanese sounds strange, but the point is, when the process spans multiple goroutines, the order in which the programs are executed is said.
In the above example, main and f are different goroutines, so their actions do not interfere with each other. However, by using the channel c, the two operations can be linked and the order of processing can be controlled.
More specifically, the operation when there is no buffer is as follows.
When the processing of main is approaching c <-1
, the processing of <-c
of f is performed before the processing of c <-1
is completed. If f is doing earlier processing, main waits until f'<-c` is complete.
Rules 1 and 2 can be summarized in Rule 3.
First, if no buffer is read as buffer 0, the sentence of rule 3 becomes as follows.
The ** k ** th receive occurs before the ** k ** th transmit from the channel ** without buffer **.
This says the same thing as Rule 2. <-c
completes before transmission c <-hoge
completes.
Regarding the presence of a buffer, substitute some values for k and C and check.
The ** 1 ** th receive occurs before the ** 2 ** th transmit from the buffer ** 1 ** channel is completed.
The ** 1 ** th receive occurs before the ** 3 ** th transmit from the buffer ** 2 ** channel is completed.
The ** 1 ** th receive occurs before the ** 101 ** th transmit from the buffer ** 100 ** channel is completed.
It says that if you want to send c <-hoge
more than the number of buffers in the channel, you must first reduce the buffer, that is, receive <-c
.
In other words, if you exceed the buffer, it is the same as for an unbuffered channel.
Also,
The ** 0 ** th reception occurs (no reception occurs) before the ** 1 ** th transmission from the buffer ** 1 ** channel is completed.
The ** -50 ** th reception occurs (≈ no reception occurs) before the ** 50 ** th transmission from the channel ** 100 ** of the buffer is completed.
In other words, transmissions that do not exceed the buffer do not have to wait for reception. And this is what Rule 1 wanted to say.
Based on these, it can be understood that Rule 3 is a summary of 1 and 2.
The following stack overflow asks and answers the above questions. The analogy of the respondents was easy to understand. https://stackoverflow.com/questions/46822673/how-to-understand-the-ch
In summary, it is as follows.
Channel ・ ・ ・ Entrance Value to be put in and out of the channel ... Delivery goroutine1 (sender) ・ ・ ・ Delivery company goroutine2 (receiver) ・ ・ ・ People who live at home
A channel with a buffer can be thought of as a front door with a parcel box. Since the delivery does not have to be at home, the delivery company can throw the luggage into the delivery box and do the next job. (Processing can be continued)
An unbuffered channel can be thought of as a front door without a parcel box.
The other party must be at home for delivery. If you are not at home, you have to wait in front of the front door until the other person returns [^ 1]. (Processing must be stopped)
That's it. If you find any mistakes in the content, please let us know in the comments.
[^ 1]: In the real world, post an absentee vote and go to the next job.
Recommended Posts