golang写屏障

发布时间:2024-07-07 16:33:12

屏障(Barrier)是一种常见的并发原语,用于协调多个并行线程的执行顺序。在Golang中,我们可以使用sync包提供的WaitGroup来实现屏障功能。WaitGroup是一个计数信号量,当其计数器为0时,等待的所有goroutine都会同时被释放。

使用sync.WaitGroup

要使用WaitGroup来实现屏障,我们首先需要创建一个WaitGroup对象,并通过Add方法初始化计数器的值。然后,每个goroutine在执行完任务后,调用Done方法来减少计数器的值。最后,我们使用Wait方法来阻塞主线程,直到所有的goroutine都执行完毕。

示例代码

下面是一个简单的示例代码,其中我们创建了5个goroutine来执行一些耗时的任务,并使用WaitGroup来实现屏障:

package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup tasks := []string{"task1", "task2", "task3", "task4", "task5"} for _, task := range tasks { wg.Add(1) go func(task string) { defer wg.Done() // 执行任务 time.Sleep(time.Second) fmt.Println(task, "done") }(task) } wg.Wait() fmt.Println("all tasks done") }

代码解析

我们首先定义了一个WaitGroup对象,并创建了一个包含5个任务的切片。然后,我们使用for循环遍历任务切片,并为每个任务调用Add方法,将计数器的值增加1。在每个goroutine执行完任务后,我们使用defer关键字在函数返回前调用Done方法,将计数器的值减少1。最后,我们调用Wait方法来阻塞主线程,直到计数器的值为0。

在每个goroutine中,我们使用匿名函数来执行具体的任务。这样可以确保每个goroutine都拥有自己独立的task变量,避免数据竞争问题。在示例代码中,我们使用time包的Sleep方法来模拟耗时的任务。你可以根据实际需求替换为其他具体的任务。

最后,当所有的goroutine都执行完任务后,我们打印出"all tasks done"来表示所有任务已经完成。

通过使用sync.WaitGroup,我们可以很方便地实现屏障功能,以确保多个并行线程按照我们期望的顺序执行。无论是大型并发程序还是简单的任务调度,都可以借助Golang提供的并发原语来简化开发。希望本文对你理解和应用屏障概念有所帮助。

相关推荐