1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| package main
import ( "fmt" "time" "math/rand" "context" "sync" "runtime" )
type Job struct { Num int64 }
type ResJob struct { JobPtr *Job Sum int64 }
func Generate(ctx context.Context, jobChan chan<- *Job) { for { select { case <-ctx.Done(): fmt.Println("Genereate done") return default: num := rand.Int63() job := &Job{Num: num} jobChan <- job } } }
func Calculate(ctx context.Context, jobChan <-chan *Job, resChan chan<- *ResJob) { for { select { case <-ctx.Done(): fmt.Println("Calculate done") return default: job := <-jobChan n := job.Num sum := int64(0) for n > 0 { sum += n % 10 n = n / 10 } res := &ResJob{ JobPtr: job, Sum: sum, } resChan <- res } } }
func main() { defer fmt.Println("NumGoroutine: ", runtime.NumGoroutine())
duration := time.Now().Add(time.Second * 5) ctx, cancel := context.WithDeadline(context.Background(), duration) defer cancel()
var jobChan = make(chan *Job, 100) var resChan = make(chan *ResJob, 100) var wg sync.WaitGroup
go Generate(ctx, jobChan)
numCalculators := 24 wg.Add(numCalculators) for i := 0; i < numCalculators; i++ { go func() { defer wg.Done() Calculate(ctx, jobChan, resChan) }() }
go func() { wg.Wait() close(resChan) }()
for { select { case <-ctx.Done(): fmt.Println("Context done") for { _, ok := <-resChan if !ok { fmt.Println("ResChan closed") break } } return case job := <-resChan: fmt.Printf("%v's the result is: %v\n", job.JobPtr.Num, job.Sum) } } }
|