Synchronization of goroutines
This lesson shows how closing or blocking a pattern, brings effective integration between goroutines.
We'll cover the following
Channels can be closed explicitly. However, they are not like files. You don’t usually need to close them. Closing a channel is only necessary when the receiver must be told that there are no more values coming. Only the sender should close a channel, never the receiver.
Closing a channel
The question is, how can we signal when sendData()
is done with the channel, and how can getData()
detect that the channel whether closed or blocked?
Signaling
This is done with the function close(ch)
. This marks the channel as unable to accept more values through a send operation <-
. Sending to or closing a closed channel causes a run-time panic. It is good practice to do this with a defer
statement immediately after the making of the channel (when it is appropriate in the given situation):
ch := make(chan float64)
defer close(ch)
Detection
This is done with the comma, ok
operator. This tests whether the channel is closed and then returns true, otherwise false. How can we test that we can receive without blocking (or that channel ch
is not closed)?
v, ok := <-ch // ok is true if v received a value
Often, this is used together with an if-statement:
if v, ok := <-ch; ok {
...
}
Or, when the receiving happens in a for loop, use break
when ch
is closed or blocked:
v, ok := <-ch
if !ok {
break
}
// process(v)
We can trigger the behavior of a non-blocking send by writing: _ = ch <- v
because the blank identifier takes whatever is sent on ch
.
Get hands-on with 1400+ tech skills courses.