testgoroutine.go 1015 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "sync"
  6. "time"
  7. )
  8. func main() {
  9. fields := []int{5, 3, 2, 6, 4} // Sleep second
  10. wg := sync.WaitGroup{}
  11. wg.Add( len(fields) )
  12. timeout := 5
  13. MAXROUTINE := 10
  14. dataChan := make(chan int, MAXROUTINE)
  15. stopChan := make(chan bool)
  16. defer close(stopChan)
  17. waitChan := make(chan bool)
  18. timeoutCtx, cancel := context.WithTimeout(context.TODO(), time.Duration(timeout) * time.Second)
  19. defer cancel()
  20. // consumer worker
  21. for i := 0; i < MAXROUTINE; i++ {
  22. // worker
  23. go func(n int) {
  24. L:
  25. for {
  26. select {
  27. case field := <-dataChan:
  28. time.Sleep(time.Second * time.Duration(field))
  29. fmt.Println("Field", field)
  30. wg.Done()
  31. case <-stopChan:
  32. break L
  33. }
  34. }
  35. }(i)
  36. }
  37. // provider
  38. go func() {
  39. for i := 0; i < len(fields); i++ {
  40. dataChan <- fields[i]
  41. }
  42. }()
  43. // wait
  44. go func() {
  45. wg.Wait()
  46. waitChan <- true
  47. }()
  48. select {
  49. case <-waitChan:
  50. fmt.Println("Run finished.")
  51. case <-timeoutCtx.Done():
  52. fmt.Println("Run timeout.")
  53. }
  54. }