ratelim.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. "strings"
  6. "sync"
  7. "time"
  8. )
  9. const (
  10. iterationsNum = 6
  11. goroutinesNum = 5
  12. quotaLimit = 2
  13. )
  14. func startWorker(in int, wg *sync.WaitGroup, quotaCh chan struct{}) {
  15. quotaCh <- struct{}{} // ratelim.go, берём свободный слот
  16. defer wg.Done()
  17. for j := 0; j < iterationsNum; j++ {
  18. fmt.Printf(formatWork(in, j))
  19. if j%2 == 0 {
  20. <-quotaCh // ratelim.go, возвращаем слот
  21. quotaCh <- struct{}{} // ratelim.go, берём слот
  22. }
  23. runtime.Gosched() // даём поработать другим горутинам
  24. }
  25. <-quotaCh // ratelim.go, возвращаем слот
  26. }
  27. func main() {
  28. wg := &sync.WaitGroup{}
  29. quotaCh := make(chan struct{}, quotaLimit) // ratelim.go
  30. for i := 0; i < goroutinesNum; i++ {
  31. wg.Add(1)
  32. go startWorker(i, wg, quotaCh)
  33. }
  34. time.Sleep(time.Millisecond)
  35. wg.Wait()
  36. }
  37. func formatWork(in, j int) string {
  38. return fmt.Sprintln(strings.Repeat(" ", in), "█",
  39. strings.Repeat(" ", goroutinesNum-in),
  40. "th", in,
  41. "iter", j, strings.Repeat("■", j))
  42. }