Skip to content

Instantly share code, notes, and snippets.

@lechuhuuha
Last active August 23, 2025 10:25
Show Gist options
  • Save lechuhuuha/81fac409cd2f35433e8ca0ee3d338df6 to your computer and use it in GitHub Desktop.
Save lechuhuuha/81fac409cd2f35433e8ca0ee3d338df6 to your computer and use it in GitHub Desktop.
Follow-up topics
package main
import (
"fmt"
"time"
)
func main() {
unbuf := make(chan int) // 0-capacity ➜ send blocks until a receiver is ready
buf := make(chan int, 2) // capacity = 2
go func() { // receiver
fmt.Println(<-unbuf) // ← blocks until sender arrives
for v := range buf { // drains buffered chan
fmt.Println(v)
}
}()
unbuf <- 1 // blocks → receiver unblocks, prints 1
buf <- 10 // enqueued (no block)
buf <- 20 // enqueued (no block, buffer full now)
// buf <- 30 // would block – buffer is full
close(buf)
time.Sleep(200 * time.Millisecond)
}
done := make(chan struct{})
ticks := time.Tick(100 * time.Millisecond) // read-only receive‐only chan
events := make(chan string, 1)
go func() {
for {
select {
case <-done: // cancellation
return
case t := <-ticks: // timeouts / periodic work
fmt.Println("tick", t)
case ev := <-events: // business events
fmt.Println("event:", ev)
default: // fall-through if nothing ready
time.Sleep(10 * time.Millisecond)
}
}
}()
events <- "file uploaded"
time.Sleep(300 * time.Millisecond)
close(done)
func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums { out <- n }
close(out)
}()
return out
}
func sq(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in { out <- n * n }
close(out)
}()
return out
}
func sum(in <-chan int) <-chan int {
out := make(chan int, 1) // buffer 1 so final send won't block
go func() {
total := 0
for n := range in { total += n }
out <- total
close(out)
}()
return out
}
func main() {
ch := gen(1, 2, 3, 4, 5)
ch = sq(ch)
result := <-sum(ch)
// cap 0 → sum hits out <- total, but nobody is reading; it stalls ⇒ goroutine leak → eventually fatal error: all goroutines are asleep – deadlock!
// cap 1 → the slot is empty; sum deposits total, closes the channel, exits. Caller can read later without blocking the producer.
fmt.Println("sum of squares:", result) // 55
}
type job struct{ id int }
type result struct{ id, squared int }
func worker(id int, jobs <-chan job, results chan<- result, wg *sync.WaitGroup) {
defer wg.Done()
for j := range jobs {
results <- result{j.id, j.id * j.id}
}
}
func main() {
const workers = 4
jobs := make(chan job, 10)
results := make(chan result, 10)
var wg sync.WaitGroup
for i := 0; i < workers; i++ {
wg.Add(1)
go worker(i, jobs, results, &wg)
}
for i := 1; i <= 8; i++ { jobs <- job{i} }
close(jobs)
go func() { wg.Wait(); close(results) }()
for r := range results {
fmt.Printf("job %d → %d\n", r.id, r.squared)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment