本质上是生产者消费者模型
    可以有效控制goroutine数量,防止暴涨
    需求:

    计算一个数字的各个位数之和,例如数字123,结果为1+2+3=6 随机生成数字进行计算

    1. package main
    2. import (
    3. "fmt"
    4. "math/rand"
    5. )
    6. type Job struct {
    7. // id
    8. Id int
    9. // 需要计算的随机数
    10. RandNum int
    11. }
    12. type Result struct {
    13. // 这里必须传对象实例
    14. job *Job
    15. // 求和
    16. sum int
    17. }
    18. func main() {
    19. // 需要2个管道
    20. // 1.job管道
    21. jobChan := make(chan *Job, 128)
    22. // 2.结果管道
    23. resultChan := make(chan *Result, 128)
    24. // 3.创建工作池
    25. createPool(64, jobChan, resultChan)
    26. // 4.开个打印的协程
    27. go func(resultChan chan *Result) {
    28. // 遍历结果管道打印
    29. for result := range resultChan {
    30. fmt.Printf("job id:%v randnum:%v result:%d\n", result.job.Id,
    31. result.job.RandNum, result.sum)
    32. }
    33. }(resultChan)
    34. var id int
    35. // 循环创建job,输入到管道
    36. for {
    37. id++
    38. // 生成随机数
    39. r_num := rand.Int()
    40. job := &Job{
    41. Id: id,
    42. RandNum: r_num,
    43. }
    44. jobChan <- job
    45. }
    46. }
    47. // 创建工作池
    48. // 参数1:开几个协程
    49. func createPool(num int, jobChan chan *Job, resultChan chan *Result) {
    50. // 根据开协程个数,去跑运行
    51. for i := 0; i < num; i++ {
    52. go func(jobChan chan *Job, resultChan chan *Result) {
    53. // 执行运算
    54. // 遍历job管道所有数据,进行相加
    55. for job := range jobChan {
    56. // 随机数接过来
    57. r_num := job.RandNum
    58. // 随机数每一位相加
    59. // 定义返回值
    60. var sum int
    61. for r_num != 0 {
    62. tmp := r_num % 10
    63. sum += tmp
    64. r_num /= 10
    65. }
    66. // 想要的结果是Result
    67. r := &Result{
    68. job: job,
    69. sum: sum,
    70. }
    71. //运算结果扔到管道
    72. resultChan <- r
    73. }
    74. }(jobChan, resultChan)
    75. }
    76. }