Skip to content

Instantly share code, notes, and snippets.

@MarcoPolo
Created May 16, 2022 20:30
Run with `GOMAXPROCS=1 go run main.go`. Note that excessive polling delays the whole function.
// You can edit this code!
// Click here and start typing.
package main
import (
"context"
"fmt"
"sync/atomic"
"time"
)
const endCondition = 100000000
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
counter := uint64(0)
go func() {
// Busy loop
for {
select {
case <-ctx.Done():
return
default:
atomic.AddUint64(&counter, 1)
}
}
}()
timer := time.NewTimer(time.Second * 2)
defer timer.Stop()
// A small number here leads to excessive polling, so progress is slower
ticker := time.NewTicker(time.Nanosecond)
// This is faster
// ticker := time.NewTicker(time.Millisecond)
defer ticker.Stop()
ch := make(chan bool, 1)
now := time.Now()
defer func() {
fmt.Println("Took:", time.Since(now))
}()
for tick := ticker.C; ; {
select {
case <-timer.C:
fmt.Println("Condition never satisfied")
return
case <-tick:
tick = nil
go func() {
if atomic.LoadUint64(&counter) > endCondition {
ch <- true
} else {
ch <- false
}
}()
case v := <-ch:
if v {
fmt.Println("Done")
return
}
tick = ticker.C
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment