运行时将创建多少个Goroutine?Go协程数量的面试疑问
Go协程数量争议问题分析
面试时我被要求编写一个包含2个Goroutine的程序,分别生成奇偶序列并同步输出数字序列。写完后面试官问运行时会创建多少个Goroutine(不算main协程),我回答是2个,但面试官不认同。我用调试器验证后结果还是2个,有没有我忽略的点?
import ( "context" "fmt" "sync" "time" ) func main() { ctx := context.Background() ch := make(chan int, 1) go func() { for { odd(ch) even(ch) } }() wg := &sync.WaitGroup{} wg.Add(1) go func() { defer wg.Done() for { time.Sleep(1 * time.Second) select { case <-ctx.Done(): return case d, ok := <-ch: if !ok { fmt.Println("channel is closed") return } fmt.Println(d) } } }() wg.Wait() } var n1 int = 1 func odd(ch chan<- int) { ch <- n1 n1 += 2 } var n2 int = 2 func even(ch chan<- int) { ch <- n2 n2 += 2 }
问题分析
- 代码中显式创建的Goroutine只有2个:
- 第一个
go func():内部循环调用odd和even函数,但这两个函数是在当前Goroutine内同步顺序执行的,并没有通过go关键字启动新的协程,所以这只是1个Goroutine。 - 第二个
go func():负责从通道接收数据并打印,这是第2个Goroutine。
- 第一个
- 不存在隐式创建的额外Goroutine:代码中用到的
context.Background()、sync.WaitGroup、time.Sleep()都不会自动创建新协程。空上下文只是一个占位符,WaitGroup是同步原语,Sleep只会阻塞当前协程,都不会启动新的执行单元。 - 可能的误解来源:面试官可能误以为
odd和even各自运行在独立Goroutine中,但实际上代码里并没有为这两个函数单独启动协程,它们只是第一个Goroutine里的普通函数调用。
内容的提问来源于stack exchange,提问作者Eshant Gupta
相关产品推荐
相关产品推荐

