MST

星途 面试题库

面试题:Go语言中Go Barrier在并行计算里如何实现基础同步

在Go语言的并行计算场景下,假设你有多个goroutine需要在某个点进行同步,类似传统语言中的barrier功能。请简要描述如何利用Go语言的特性(如channel、sync包等)来实现一个简易的Go Barrier机制,用于同步这些goroutine,使得所有goroutine到达barrier点后再一起继续执行后续代码,并给出相关代码示例。
45.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 使用sync.WaitGroup来等待所有goroutine到达barrier点。
  2. 使用一个channel来通知所有goroutine可以继续执行。

代码示例

package main

import (
    "fmt"
    "sync"
)

// Barrier 定义Barrier结构体
type Barrier struct {
    n    int
    wg   sync.WaitGroup
    done chan struct{}
}

// NewBarrier 创建一个新的Barrier
func NewBarrier(n int) *Barrier {
    return &Barrier{
        n:    n,
        done: make(chan struct{}),
    }
}

// Wait 等待所有goroutine到达barrier
func (b *Barrier) Wait() {
    b.wg.Add(1)
    go func() {
        defer b.wg.Done()
        b.wg.Wait()
        close(b.done)
    }()
    <-b.done
}

func main() {
    numGoroutines := 5
    barrier := NewBarrier(numGoroutines)

    for i := 0; i < numGoroutines; i++ {
        go func(id int) {
            fmt.Printf("Goroutine %d is running\n", id)
            barrier.Wait()
            fmt.Printf("Goroutine %d passed the barrier\n", id)
        }(i)
    }

    // 防止主线程退出
    select {}
}

在上述代码中:

  1. Barrier结构体包含了等待的goroutine数量n,一个sync.WaitGroup用于等待所有goroutine到达,以及一个channel done用于通知所有goroutine可以继续执行。
  2. NewBarrier函数用于初始化Barrier
  3. Wait方法中,每个goroutine调用wg.Add(1)来增加等待组的计数,然后启动一个新的goroutine来等待所有goroutine到达(通过wg.Wait()),当所有goroutine到达后,关闭done通道,通知所有等待的goroutine继续执行。

main函数中,创建了多个goroutine并让它们在执行过程中通过barrier.Wait()进行同步。