n个协程交替打印1-100,详细注释

go实现n个goroutine交替打印 1- 100

这道题是面试时经常遇到的一道题,是考察对goroutine和channel的应用

思路:创建等同goroutine数量的chan切片,每个chan通过阻塞的性质控制goroutine的顺序

func alternatingNGoroutine() {
	chanNum := 5                           // chan数量代表着goroutine数量
	chanQueue := make([]chan int, chanNum) // chan切片
	exitChan := make(chan bool)            // 退出信号
	res := 0
	for i := 0; i < chanNum; i++ {
		// 初始化chan切片的每个chan,无缓冲的
		chanQueue[i] = make(chan int)
		// 这个我在下面详细解释,很重要,没有这个会死锁
		if i == chanNum-1 {
			go func(i int) {
				chanQueue[i] <- 1
			}(i)
		}
	}

	// for循环创建goroutine
	for i := 0; i < chanNum; i++ {
		// prevChan 是等前一个协程结束才能输出下一个,为了控制输出顺序
		// curChan 控制当前阻塞输出的协程
		var prevChan, curChan chan int
		if i == 0 {
			// chan切片想象成一个环,第一个切片的前一个就是chan切片的末尾,和上面相呼应,就是要给最后一个chan先发送一条消息
			prevChan = chanQueue[chanNum-1]
		} else {
			// 记录前一个协程状态
			prevChan = chanQueue[i-1]
		}
		// 记录当前协程
		curChan = chanQueue[i]

		go func(i int, prevChan, curChan chan int) {
			for {
				// 如果大于100就退出
				if res > 100 {
					exitChan <- true
				}
				// 一直阻塞到上一个输出完,控制顺序
				<-prevChan
				fmt.Println("goroutine", i, ": ", res)
				res++
				// 当前协程输出完
				curChan <- 1
			}
		}(i, prevChan, curChan)
	}

	<-exitChan
	fmt.Println("done...")
}
		if i == chanNum-1 {
			go func(i int) {
				chanQueue[i] <- 1
			}(i)
		}

1、这一步主要是给最后一个chan先发送数据,保证第一个chan可以取到数据不阻塞

2、必须要加协程去发送这条数据,不然直接死锁了,因为不是协程发数据就会一直阻塞导致死锁

相关推荐

  1. n个协交替打印1-100详细注释

    2024-03-13 16:34:02       19 阅读
  2. 多线交替打印

    2024-03-13 16:34:02       28 阅读
  3. (C)1005 继续(3n+1)猜想

    2024-03-13 16:34:02       17 阅读
  4. 1002 - 编程求解1+2+3+...+n

    2024-03-13 16:34:02       16 阅读
  5. 1003 - 编程求1+3+5+...+n

    2024-03-13 16:34:02       10 阅读
  6. 手撕面试题:多线交叉打印ABC

    2024-03-13 16:34:02       21 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-13 16:34:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-13 16:34:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-13 16:34:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-13 16:34:02       18 阅读

热门阅读

  1. 蓝桥杯刷题(五)

    2024-03-13 16:34:02       17 阅读
  2. 【Spring高级】Aware与InitializingBean接口

    2024-03-13 16:34:02       17 阅读
  3. C语言每日一题(63)复写零

    2024-03-13 16:34:02       17 阅读
  4. [蓝桥杯 2019 省 B] 等差数列

    2024-03-13 16:34:02       17 阅读
  5. js静态分析,babel编译,vue的template编译

    2024-03-13 16:34:02       18 阅读
  6. 经典面试题HTTP请求主要有以下几种方式

    2024-03-13 16:34:02       23 阅读
  7. vue虚拟DOM的简答

    2024-03-13 16:34:02       21 阅读
  8. Mysql索引两种排序方式分析

    2024-03-13 16:34:02       21 阅读