插件窝 干货文章 Go语言中如何用单个Channel保证多个Goroutine同步输出?

Go语言中如何用单个Channel保证多个Goroutine同步输出?

Goroutine Channel 所有 输出 599    来源:    2025-03-13

在Go语言中,可以使用单个Channel来保证多个Goroutine同步输出。具体来说,可以通过Channel的阻塞特性来控制Goroutine的执行顺序,确保它们按照预期的顺序输出。

以下是一个示例代码,展示了如何使用单个Channel来同步多个Goroutine的输出:

package main

import (
    "fmt"
    "sync"
)

func main() {
    // 创建一个用于同步的Channel
    syncChan := make(chan struct{})

    // 使用WaitGroup来等待所有Goroutine完成
    var wg sync.WaitGroup

    // 启动多个Goroutine
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            // 等待Channel的信号
            <-syncChan
            // 输出Goroutine的ID
            fmt.Printf("Goroutine %d is running\n", id)
        }(i)
    }

    // 主Goroutine等待一段时间,确保所有Goroutine都已经启动并等待Channel的信号
    // 在实际应用中,这一步可能不需要
    time.Sleep(time.Second)

    // 向Channel发送信号,触发所有Goroutine的输出
    close(syncChan)

    // 等待所有Goroutine完成
    wg.Wait()
}

代码解释:

  1. syncChan: 这是一个无缓冲的Channel,用于同步多个Goroutine的执行。所有Goroutine都会在<-syncChan处阻塞,直到Channel被关闭。

  2. wg: 这是一个sync.WaitGroup,用于等待所有Goroutine完成。每个Goroutine在启动时调用wg.Add(1),在完成时调用wg.Done()

  3. Goroutine: 每个Goroutine在启动后会立即阻塞在<-syncChan处,等待Channel的信号。当Channel被关闭时,所有阻塞的Goroutine会同时被唤醒,并继续执行后续的代码。

  4. close(syncChan): 主Goroutine在确保所有Goroutine都已经启动并等待Channel的信号后,关闭Channel。这会触发所有阻塞的Goroutine继续执行。

  5. wg.Wait(): 主Goroutine等待所有Goroutine完成。

输出结果:

由于所有Goroutine都在等待同一个Channel的信号,当Channel被关闭时,它们会同时被唤醒并输出。输出的顺序可能会有所不同,因为Goroutine的执行顺序是不确定的。

Goroutine 0 is running
Goroutine 1 is running
Goroutine 2 is running
Goroutine 3 is running
Goroutine 4 is running

注意事项:

  • 如果希望Goroutine按照特定的顺序输出,可以使用多个Channel或其他同步机制来控制执行顺序。
  • 在实际应用中,可能需要根据具体需求调整Channel的类型和同步逻辑。

通过这种方式,你可以使用单个Channel来同步多个Goroutine的输出。