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()
}
并发任务处理系统
778

被折叠的 条评论
为什么被折叠?



