Skip to content

Latest commit

 

History

History
124 lines (96 loc) · 3.52 KB

concurrency.channels.md

File metadata and controls

124 lines (96 loc) · 3.52 KB

Overview

  1. Key features & usage idioms for a channel

Key Concepts

  1. Type-safe
  2. Thread-safe (goroutine safe)
  3. FIFO queue
  4. Pass-by-address-value
    1. All things pass by value
    2. maps, slices, channels, functions are passed by "address" value (like a pointer)
    3. If you pass a channel to a function/method, caller & callee are referencing the same channel
  5. Optionally buffered
    1. Only affects Senders (Not receivers)
  6. Go channels are designed for 1 writer, and multiple readers
  7. range will NOT stop recieving util channel is closed
  8. Sender is responsible for closing channel
    1. If you have multiple senders, use a sync.WaitGroup to close when done

Creation

  1. allocated with make
// unbuffered channel of ints
c1 := make(chan int)

// unbuffered channel of empty struct (zero memory)
c2 := make(chan struct{})

// buffered channel of strings, capacity of 5
c3 := make(chan string, 5)

Buffering: Unbuffered channel

  • sender blocks for first receiver
  • receiver blocks for sender

Buffering: buffered channel

  • Buffer size == how many values to accept without a receiver

Sender

  1. runtime will panic if you send on a closed channel
  2. Blocks when ...
    1. (unbounded) Unbuffered and receiver hasn't received
    2. (unbounded) writing to a full buffer (until there's buffer capacity)
    3. (briefly) writing to the non-full buffer (just long enough to commit the value)
  3. Send example:
responseCodeCh <- 200
  1. send on nil channel blocks forever
  2. Sender side is responsible for closing the channel
    1. If you have multiple senders, use a sync.WaitGroup to close when done

Receiver

  1. Blocks when ...
    1. (unbounded) no messages available
    2. (unbounded) when buffer empty
  2. Reading from closed channel yields zero value immediately
  3. Only receiver can check if channel is closed
  4. Receive:
//TODO
  1. You can also use select + default for non-blocking
  2. receive on nil channel blocks forever
  3. even if you read a channel using receive-assign syntax, it will block until there's a message or channel is closed
  • TODO: range

Direction: Two-way

TODO

Receive only channel

  1. Example
func myReceiver(source <-chan bool) {
    current := <-source
    fmt.Println("I read this: %v", current)
}

TODO: more here

Send only channel

  1. Writing to closed channel causes panic
  2. Example
func mySender(sink chan<- bool) {
    sink <- true
}

TODO: more here

select block

TODO TODO: https://www.golang-book.com/books/intro/10

Idioms

  1. Use one-way channels as function args
  • TODO: nil channel
  • TODO: closed channel
  • TODO: closing a channel
  • TODO: channel with empty struct

Other Resources

  1. Language spec
  2. go101
  3. gobyexample
  4. Official tour
  5. yourbasic
  6. https://go101.org/article/channel-closing.html
  7. https://github.com/karanpratapsingh/learn-go#channels
  8. https://github.com/lotusirous/go-concurrency-patterns