go实现多队列并发

1、场景描述

       假设有一个任务,分成A、B、C、D四个步骤,四个步骤的耗时差别很大,且不同的任务可能是B的耗时最长,也有可能是D的耗时最长,步骤B和C依赖步骤A,步骤D依赖B和C。为了提高性能,故实现任务之间的并发。

2、具体实现

      用四个队列分别完成任务中的每个步骤,队列之间是并发的,队列中可以顺序执行也可以并发执行(比如queue_B)

package main

import (
   "fmt"
   "sync"
   "time"
   "math/rand"
   "github.com/pbenner/threadpool"
)

type Product struct {
   name   string
   result string
   isStop bool
}

func queue_A(wg *sync.WaitGroup, A_B chan<- Product, A_C chan<- Product, app []string) {
   defer wg.Done()

   for i, appname := range app {
      product := Product{name: appname, result: "success", isStop: false}
      if i == len(app)-1 {
         product.isStop = true
      }
      A_B <- product
      A_C <- product
      fmt.Println("任务A:", appname)
      time.Sleep(time.Duration(200+rand.Intn(1000)) * time.Millisecond)
   }
}

func queue_B(wg *sync.WaitGroup, A_B <-chan Product, B_D chan<- Product, app []string) {
   defer wg.Done()
   pool := threadpool.New(3, 100)

   // jobs are always grouped, get a new group index
   g := pool.NewJobGroup()
   isStop := false
   for {
      if isStop {
         break
      }
      com := <-A_B
      isStop = com.isStop

      time.Sleep(time.Duration(200+rand.Intn(1000)) * time.Millisecond)
      pool.AddJob(g, func(pool threadpool.ThreadPool, erf func() error) error {
         i := pool.GetThreadId() + 1
         fmt.Println(i)
         return task(com, B_D)
      })
      // wait until all jobs in group g are done, meanwhile, this thread
      // is also used as a worker

   }
   pool.Wait(g)

}
func task(com Product, B_D chan<- Product) error {
   time.Sleep(3 * time.Second)
   fmt.Println("任务B:", com.name)

   product := Product{name: com.name, result: "success", isStop: false}
   if com.isStop {
      product.isStop = true
   }
   B_D <- com
   return nil
}
func queue_C(wg *sync.WaitGroup, A_C <-chan Product, C_D chan<- Product, app []string) {
   defer wg.Done()
   isStop := false
   for {
      if isStop {
         break
      }
      pvc := <-A_C
      isStop = pvc.isStop
      time.Sleep(time.Duration(200+rand.Intn(1000)) * time.Millisecond)

      fmt.Println("任务C:", pvc.name)

      product := Product{name: pvc.name, result: "success", isStop: false}
      if pvc.isStop {
         product.isStop = true
      }
      C_D <- pvc
   }

}

func queue_D(wg *sync.WaitGroup, C_D <-chan Product, B_D <-chan Product, app []string) {
   defer wg.Done()
   isStop := false
   for {
      if isStop {
         break
      }
      pvc := <-C_D
      com := <-B_D
      if pvc.isStop || com.isStop {
         isStop = true
      }
      time.Sleep(time.Duration(200+rand.Intn(1000)) * time.Millisecond)
      fmt.Println("任务D:", pvc.name, com.name)

   }

}
func main() {
   wgp := &sync.WaitGroup{}
   wgp.Add(4)
   app := []string{"app1", "app2", "app3", "app4", "app5", "app6", "app7", "app8", "app9",}
   A_B := make(chan Product, len(app))
   A_C := make(chan Product, len(app))
   B_D := make(chan Product, len(app))
   C_D := make(chan Product, len(app))
   defer close(A_B)
   defer close(A_C)
   defer close(B_D)
   defer close(C_D)

   go queue_A(wgp, A_B, A_C, app)
   go queue_B(wgp, A_B, B_D, app)
   go queue_C(wgp, A_C, C_D, app)
   go queue_D(wgp, C_D, B_D, app)
   time.Sleep(time.Duration(1) * time.Second)
   wgp.Wait()
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值