4

Channels offer synchronized communication

 3 years ago
source link: https://yourbasic.org/golang/channels-explained/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Channels offer synchronized communication

yourbasic.org/golang

A channel is a mechanism for goroutines to synchronize execution and communicate by passing values.

sushi conveyor belt

A new channel value can be made using the built-in function make.

// unbuffered channel of ints
ic := make(chan int)

// buffered channel with room for 10 strings
sc := make(chan string, 10)

To send a value on a channel, use <- as a binary operator. To receive a value on a channel, use it as a unary operator.

ic <- 3   // Send 3 on the channel.
n := <-sc // Receive a string from the channel.

The <- operator specifies the channel direction, send or receive. If no direction is given, the channel is bi-directional.

chan Sushi    // can be used to send and receive values of type Sushi
chan<- string // can only be used to send strings
<-chan int    // can only be used to receive ints

Buffered and unbuffered channels

  • If the capacity of a channel is zero or absent, the channel is unbuffered and the sender blocks until the receiver has received the value.
  • If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.
  • Receivers always block until there is data to receive.
  • Sending or receiving from a nil channel blocks forever.

Closing a channel

The close function records that no more values will be sent on a channel. Note that it is only necessary to close a channel if a receiver is looking for a close.

  • After calling close, and after any previously sent values have been received, receive operations will return a zero value without blocking.
  • A multi-valued receive operation additionally returns an indication of whether the channel is closed.
  • Sending to or closing a closed channel causes a run-time panic. Closing a nil channel also causes a run-time panic.
ch := make(chan string)
go func() {
    ch <- "Hello!"
    close(ch)
}()

fmt.Println(<-ch) // Print "Hello!".
fmt.Println(<-ch) // Print the zero value "" without blocking.
fmt.Println(<-ch) // Once again print "".
v, ok := <-ch     // v is "", ok is false.

// Receive values from ch until closed.
for v := range ch {
    fmt.Println(v) // Will not be executed.
}

Example

In the following example we let the Publish function return a channel, which is used to broadcast a message when the text has been published.

// Publish prints text to stdout after the given time has expired.
// It closes the wait channel when the text has been published.
func Publish(text string, delay time.Duration) (wait <-chan struct{}) {
	ch := make(chan struct{})
	go func() {
		time.Sleep(delay)
		fmt.Println(text)
		close(ch)
	}()
	return ch
}

Note that we use a channel of empty structs to indicate that the channel will only be used for signalling, not for passing data. This is how you might use the function.

wait := Publish("important news", 2 * time.Minute)
// Do some more work.
<-wait // Block until the text has been published.

Share:             


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK