goroutine什么时候会阻塞main函数?

156 阅读1分钟

在Go语言中,主要有两种情况会导致main函数被阻塞,不让其快速退出:

  1. 等待goroutine完成:如果在main函数中启动了一个或多个goroutine,并且需要等待这些goroutine执行完成后再退出,可以使用sync.WaitGroup或者channel来实现等待。这样可以确保main函数在所有goroutine执行完成后再退出。

示例代码:

package main

import (
	"fmt"
	"sync"
)

func worker(wg *sync.WaitGroup) {
	defer wg.Done()
	// 执行一些任务
}

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 3; i++ {
		wg.Add(1)
		go worker(&wg)
	}

	wg.Wait() // 等待所有goroutine执行完成
	fmt.Println("所有goroutine执行完成,main函数退出")
}
  1. 从channel接收数据:如果main函数需要从channel接收数据,但是channel中没有数据时,main函数会被阻塞,直到有数据可接收或者channel关闭。

示例代码:

package main

import "fmt"

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

	go func() {
		ch <- 42
		close(ch)
	}()

	value, ok := <-ch
	fmt.Println(value, ok) // 输出: 42 true

	value, ok = <-ch // 通道已关闭,接收到的是零值,且ok为false
	fmt.Println(value, ok) // 输出: 0 false
}

在这个示例中,main函数从通道ch中接收数据,当通道被关闭后,再次接收数据会得到通道元素的零值,并且ok的值为false,从而导致main函数被阻塞。