3. 如何控制协程执行顺序
此开源图书由ithaiq原创,创作不易转载请注明出处
对应两个协程勿扰质疑可以通过两个channel先后触发即可,还可以交替执行
如交替打印数字和字母,实现如下效果:12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ
func main() {
wg := &sync.WaitGroup{}
numChan := make(chan struct{}, 1)
byteChan := make(chan struct{}, 1)
wg.Add(2)
numChan <- struct{}{}
go numPrint(wg, numChan, byteChan)
go bytePrint(wg, numChan, byteChan)
wg.Wait()
}
func numPrint(wg *sync.WaitGroup, numChan, byteChan chan struct{}) {
i := 1
for {
if i == 27 {
wg.Done()
break
}
<-numChan
println(i, i+1)
i += 2
byteChan <- struct{}{}
}
}
func bytePrint(wg *sync.WaitGroup, numChan, byteChan chan struct{}) {
i := 'A'
for {
if i > 'Z' {
wg.Done()
break
}
<-byteChan
fmt.Printf("%c%c", i, i+1)
i += 2
numChan <- struct{}{}
}
}
延伸开来,如果N个协程如何控制执行顺序?考虑使用sync.Cond
var co *sync.Cond
var group int
func work1() {
fmt.Println("work1")
for i := 1; i <= 3; i++ {
//业务处理
co.L.Lock()
group = i
co.L.Unlock()
co.Broadcast()
time.Sleep(time.Second * 1)
}
}
func work2() {
co.L.Lock()
for group != 2 {
co.Wait()
}
time.Sleep(time.Second * 4)
fmt.Println("work2")
co.L.Unlock()
}
func work3() {
co.L.Lock()
for group != 3 {
co.Wait()
}
time.Sleep(time.Second * 2)
fmt.Println("work3")
co.L.Unlock()
}
func dowork(wg *sync.WaitGroup, fns ...func()) {
for _, fn := range fns {
wg.Add(1)
go func(fn func()) {
defer wg.Done()
fn()
}(fn)
}
}
func main() {
var wg sync.WaitGroup
co = sync.NewCond(new(sync.Mutex))
dowork(&wg, work1, work2, work3)
wg.Wait()
}
如上代码演示主要是Broadcast广播任意goroutine都能收到Wait解除阻塞,然后通过互斥锁mutex控制全局变量group,而group再去控制执行顺序
最后更新于
这有帮助吗?