Golang中func printCounts为何会运行十次?求解释

Golang中func printCounts为何会运行十次?求解释

package main

import (
	"fmt"
	"sync"
)

// wg 用于等待程序完成。
var wg sync.WaitGroup

func main() {
	count := make(chan int)

	// 添加计数为2,每个goroutine一个。
	wg.Add(2)

	fmt.Println("启动 Goroutines")

	// 启动一个标签为 "Goroutine-1" 的 goroutine
	go printCounts("Goroutine-1", count)

	// 启动一个标签为 "Goroutine-2" 的 goroutine
	go printCounts("Goroutine-2", count)

	fmt.Println("通道通信开始")
	count <- 1

	// 等待 goroutine 完成。
	fmt.Println("等待完成")
	wg.Wait()
	fmt.Println("\n终止程序")
}
func printCounts(label string, count chan int) {

	// 安排调用 WaitGroup 的 Done 来告知 goroutine 已完成。
	defer wg.Done()
	for val := range count {
		fmt.Printf("计数: %d 来自 %s \n", val, label)

		if val == 10 {
			fmt.Printf("通道从 %s 关闭 \n", label)

			// 关闭通道
			close(count)
			return
		}
		val++

		// 将计数发送回另一个 goroutine。
		count <- val
	}
}

更多关于Golang中func printCounts为何会运行十次?求解释的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

谢谢你,Sean!

更多关于Golang中func printCounts为何会运行十次?求解释的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的,完成了!现在你能为我解释一下这段代码吗?

请以可读的方式格式化您问题中的代码。这可以通过选择代码并点击编辑窗口顶部的</>按钮轻松完成。

printCounts 并未运行十次。在 printCounts 函数中有一个 for val := range count 循环,该循环会在 Goroutine-1 和 Goroutine-2 之间持续“乒乓”传递一个递增的计数值,直到该计数值达到 10。此时,通道被关闭,因此两个 Goroutine 都会退出循环以及 printCounts 函数。

printCounts 函数运行十次是因为两个 goroutine 通过通道进行乒乓式通信,交替递增计数值。具体执行流程如下:

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func main() {
	count := make(chan int)
	wg.Add(2)

	go printCounts("Goroutine-1", count)
	go printCounts("Goroutine-2", count)

	count <- 1  // 发送初始值1
	wg.Wait()
}

func printCounts(label string, count chan int) {
	defer wg.Done()
	for val := range count {
		fmt.Printf("计数: %d 来自 %s \n", val, label)

		if val == 10 {
			fmt.Printf("通道从 %s 关闭 \n", label)
			close(count)
			return
		}
		val++
		count <- val  // 递增后发送给另一个goroutine
	}
}

执行顺序分析:

  1. 初始状态:通道为空,两个goroutine阻塞在for val := range count
  2. 主协程count <- 1 发送初始值
  3. Goroutine-1:接收值1,打印,递增到2,发送2到通道
  4. Goroutine-2:接收值2,打印,递增到3,发送3到通道
  5. 交替执行:两个goroutine轮流处理数值,每次递增1
  6. 终止条件:当某个goroutine收到10时关闭通道

执行轨迹示例:

计数: 1 来自 Goroutine-1  // 第1次
计数: 2 来自 Goroutine-2  // 第2次
计数: 3 来自 Goroutine-1  // 第3次
计数: 4 来自 Goroutine-2  // 第4次
计数: 5 来自 Goroutine-1  // 第5次
计数: 6 来自 Goroutine-2  // 第6次
计数: 7 来自 Goroutine-1  // 第7次
计数: 8 来自 Goroutine-2  // 第8次
计数: 9 来自 Goroutine-1  // 第9次
计数: 10 来自 Goroutine-2 // 第10次
通道从 Goroutine-2 关闭

关键机制:

  • 通道count是无缓冲的,发送和接收会同步阻塞
  • for val := range count 会持续接收直到通道关闭
  • 两个goroutine形成生产-消费循环,直到值达到10

这就是为什么总共打印10次(1到10),每个goroutine各执行5次,通过通道交替传递递增的数值。

回到顶部