两个协程交替打印
两个协程交替打印
两个channel
思路: 使用两个通道,一个协程从自己的通道中取出数,然后向对方的通道中放一个数
代码:
// 两个协程
func printA(c1, c2 chan int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i <= 100; i++ {
<-c1
if i%2 == 0 {
fmt.Println("goroutine A is printing:", i)
}
c2 <- 100
}
}
func printB(c1, c2 chan int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i <= 100; i++ {
<-c2
if i%2 == 1 {
fmt.Println("goroutine B is printing:", i)
}
c1 <- 100
}
}
func Method1() {
wg := &sync.WaitGroup{}
c1 := make(chan int,1) // 要加缓冲区,不然死锁
c2 := make(chan int,1)
wg.Add(2)
go printA(c1, c2, wg)
go printB(c1, c2, wg)
c1<-1 // 启动打印
wg.Wait()
}
一个channel
思路: 用一个通道,一个协程去取数,一个往通道里放数,达到交替效果
但是这种方法有问题,就是一存一取的情况下,两个协程其实是同时可以继续向下运行的,这里是靠判断 i 的奇偶错开了他们。
代码:
// 这种使用channel的方法其实是有问题的,因为对于无缓冲的channel,一边进了之后,另一边的出会同时满足,所以如果去掉奇偶判断,就会出现错误的结果。
var ChanSignal = make(chan int)
var wg = sync.WaitGroup{}
func Method2() {
wg.Add(2)
go printAA()
go printBB()
wg.Wait()
}
func printAA() {
defer wg.Done()
for i := 0; i < 101; i++ {
ChanSignal <- 1
if i%2 == 1 {
fmt.Println("AAAA:", i)
}
}
}
func printBB() {
defer wg.Done()
for i := 0; i < 101; i++ {
<-ChanSignal
if i%2 == 0 {
fmt.Println("BBBB:", i)
}
}
}