Golang Concurrency #4 - Channel operations

Just a guy who loves to write code and watch anime.
Send and Receive (Covered in previous post)
ch <- value // Send
value := <-ch // Receive
Closing Channels
close(ch)
Signals "no more values will be sent"
Receivers can still read remaining values
Sending to closed channel = panic
Checking if channel is closed
value, ok := <-ch
if !ok {
// Channel is closed and empty
}
Buffered vs Unbuffered Channels
Unbuffered (default)
ch := make(chan int) // Buffer size 0
Sender blocks until receiver is ready
Receiver blocks until sender sends
Synchronous handoff
Buffered
ch := make(chan int, 3) // Buffer size 3
Sender only blocks when buffer is full
Receiver only blocks when buffer is empty
Asynchronous up to buffer size
Buffered example
ch := make(chan int, 2)
ch <- 1 // Doesn't block, buffer has space
ch <- 2 // Doesn't block, buffer has space
ch <- 3 // BLOCKS! Buffer is full
fmt.Println(<-ch) // Prints 1, frees buffer space
ch <- 3 // Now this works
When to use buffered
When you want to decouple sender/receiver timing
When you know how many items you'll process
For performance (reduce blocking)
When to use unbuffered
When you want synchronization (sender waits for receiver)
For simple request-response patterns
When you want guaranteed delivery
More notes
Receiving removes from channel
ch := make(chan int, 2)
ch <- 10
ch <- 20
first := <-ch // Takes 10 out of channel
second := <-ch // Takes 20 out of channel
third := <-ch // Channel is now empty, this blocks
Once you receive a value, it's gone from the channel.
Buffer is exactly like a queue (FIFO - First In, First Out)
ch := make(chan int, 3)
ch <- 1 // Queue: [1]
ch <- 2 // Queue: [1, 2]
ch <- 3 // Queue: [1, 2, 3]
fmt.Println(<-ch) // Gets 1, Queue: [2, 3]
fmt.Println(<-ch) // Gets 2, Queue: [3]
fmt.Println(<-ch) // Gets 3, Queue: []
Non-blocking = other code runs
ch := make(chan int, 2)
ch <- 1 // Doesn't block, continues immediately
ch <- 2 // Doesn't block, continues immediately
fmt.Println("This runs right away!")
ch <- 3 // NOW it blocks, waiting for buffer space
fmt.Println("This waits until someone receives")
Blocking = everything stops
ch := make(chan int) // Unbuffered
ch <- 1 // BLOCKS here, waiting for receiver
fmt.Println("This never runs until someone receives")






