面试题答案
一键面试实现思路
- 使用
sync.WaitGroup
来等待所有goroutine到达barrier点。 - 使用一个
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 {}
}
在上述代码中:
Barrier
结构体包含了等待的goroutine数量n
,一个sync.WaitGroup
用于等待所有goroutine到达,以及一个channel
done
用于通知所有goroutine可以继续执行。NewBarrier
函数用于初始化Barrier
。Wait
方法中,每个goroutine调用wg.Add(1)
来增加等待组的计数,然后启动一个新的goroutine来等待所有goroutine到达(通过wg.Wait()
),当所有goroutine到达后,关闭done
通道,通知所有等待的goroutine继续执行。
在main
函数中,创建了多个goroutine并让它们在执行过程中通过barrier.Wait()
进行同步。