两个协程交替打印

两个协程交替打印

两个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)
		}
	}

}
posted @ 2022-09-25 23:45  博客是个啥?  阅读(103)  评论(0编辑  收藏  举报