Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "flag"
- "fmt"
- "sync"
- "time"
- )
- var withLock = flag.Bool("lock", false, "use lock on resets")
- var withStop = flag.Bool("stop", false, "use stop and channel drain on resets")
- func main() {
- flag.Parse()
- fmt.Printf("lock: %v; stop: %v\n", *withLock, *withStop)
- var (
- resetGoroutines sync.WaitGroup
- timers sync.WaitGroup
- delays sync.WaitGroup
- )
- var (
- startReset = make(chan struct{})
- stopReset = make(chan struct{})
- )
- const (
- timersCount = 4
- resetGoroutinesCount = 32
- resetTo = time.Millisecond * 600
- resetInterval = resetTo / 6
- )
- timers.Add(timersCount)
- delays.Add(timersCount)
- for i := 0; i < timersCount; i++ {
- go func(x int) {
- tm := time.AfterFunc(time.Hour, func() {
- fmt.Printf("timer #%d fired\n", x)
- delays.Done()
- })
- timers.Done()
- var mu sync.Mutex
- resetGoroutines.Add(resetGoroutinesCount)
- for i := 0; i < resetGoroutinesCount; i++ {
- go func(i int) {
- defer resetGoroutines.Done()
- <-startReset
- tick := time.NewTicker(resetInterval)
- for {
- select {
- case <-tick.C:
- if *withLock {
- mu.Lock()
- }
- if *withStop {
- if !tm.Stop() {
- select {
- case <-tm.C:
- default:
- }
- }
- }
- tm.Reset(resetTo)
- if *withLock {
- mu.Unlock()
- }
- case <-stopReset:
- return
- }
- }
- }(i)
- }
- }(i)
- }
- timers.Wait()
- fmt.Printf("initialized %d timers\n", timersCount)
- close(startReset)
- fmt.Printf("will sleep for %s x 4 (delay which is set during resets)\n", resetTo)
- time.Sleep(resetTo * 4)
- close(stopReset)
- fmt.Println("done, waiting...")
- resetGoroutines.Wait()
- fmt.Println("reset goroutines are done")
- delays.Wait()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement