【GoLang】协程练习题

题目

编写一个程序,实现以下功能:

  1. 创建一个协程,用于打印数字1到10;

  2. 创建另一个协程,用于打印字母A到J;

  3. 确保数字和字母的输出交替进行;

  4. 主线程等待两个协程完成后退出。

要求:

  1. 使用Go语言的协程(goroutine)实现并发;

  2. 使用适当的同步机制,以确保数字和字母的输出交替进行;

  3. 代码结构清晰,包含适当的注释。

先看代码


func main() {
	var wg sync.WaitGroup

	// 需要等待2个协程完成
	wg.Add(2)

	// 使用channel来控制输出顺序
	numCh := make(chan bool, 1)
	letterCh := make(chan bool, 1)

	// 启动数字输出协程
	go func() {
		// 通知waitGroup 一个协程已经完成
		defer wg.Done()
		defer close(letterCh)

		for i := 1; i <= 10; i++ {
			<-numCh
			fmt.Printf("%d ", i)
			letterCh <- true
		}
	}()

	// 启动字母输出协程
	go func() {
		// 通知waitGroup 一个协程已经完成
		defer wg.Done()
		defer close(numCh)

		for c := 'A'; c <= 'J'; c++ {
			<-letterCh
			fmt.Printf("%c ", c)
			numCh <- true
		}
	}()

	// 启动输出
	numCh <- true

	// 等待两个协程完成
	wg.Wait()
}

输出结果:
1 A 2 B 3 C 4 D 5 E 6 F 7 G 8 H 9 I 10 J

思路

实现交替

本题的关键在于数字和字母的输出要交替进行,那么如何实现交替呢?我们都知道,两个协程同时开启时,执行的先后顺序是不确定的。而 channel 就可以很好的解决这个问题。
我们把channel理解成是高速路口的起落杆,遵循一车一杆的原则,杆子抬起表示从channel中取出数据,杆子落下表示无法从channel中取出数据(阻塞)。
杆子抬起,输出数字,杆子落下。杆子抬起,输出字母,杆子落下。杆子抬起,输出数字,杆子落下。。。如此往复。

实现主线程等待协程完成

为避免协程还未结束,主线程就已经结束了的情况,我们这里用到了sync.WaitGroup来解决这个问题。

WaitGroup 对象内部有一个计数器,最初从0开始,它有三个方法:Add(),Done(),Wait()用来控制计数器的数量。Add(n)把计数器的值设置为n,Done() 每次把计数器的值 -1,wait()会阻塞代码的运行,直到计数器地值减为0。

关闭channel

为避免出现内存泄漏等问题,我们在使用完channel时,需要通过函数close() 将其关闭。

但是在本题中,channel的发送数量和接收数量都确定且相等,所以不会出现内存泄漏问题,故不关闭也行。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值