下面详细讲解如何使用sync.WaitGroup
实现协程同步的完整攻略。
什么是协程同步?
在使用协程进行并发编程时,我们常常需要等待所有协程都执行完毕后再进行某些操作,这时候我们就需要协程同步。协程同步指的是在并发编程中,协调多个协程的执行顺序,确保它们可以在特定的时间点同步。
WaitGroup的使用
WaitGroup
是Go语言中提供的一种机制,它可以用来等待一组协程的执行完成。在创建协程时,我们把WaitGroup的计数器加1,每个协程执行完毕后,我们再把计数器减1。在所有协程都执行完毕后,计数器的值为0,程序才能继续向下执行。
WaitGroup中包含两个方法,一个是Add方法,用于将计数器加1;一个是Done方法,用于将计数器减1;另一个是Wait方法,用于等待计数器值为0。
下面是一个使用WaitGroup
进行协程同步的例子:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
fmt.Println("协程1执行完毕")
}()
go func() {
defer wg.Done()
fmt.Println("协程2执行完毕")
}()
wg.Wait()
fmt.Println("所有协程执行完毕")
}
在这个例子中,我们创建了两个协程,使用wg.Add(2)
将计数器值设为2,然后每个协程执行完毕后都会调用wg.Done()
,减少计数器的值。最后,wg.Wait()
会一直等待,直到计数器值变为0,程序才会继续执行。
使用WaitGroup实现批量下载文件
实际应用中,我们可以使用WaitGroup
实现文件的批量下载。例如,我们需要下载100个文件,使用协程同时下载可以提高下载速度,但是我们需要确保所有文件都下载完成后再进行合并。
下面是一个使用WaitGroup
实现批量下载文件的例子:
package main
import (
"fmt"
"io"
"net/http"
"os"
"sync"
)
func downloadFile(url string, filename string, wg *sync.WaitGroup) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
fmt.Println("下载失败:", err)
return
}
defer resp.Body.Close()
file, err := os.Create(filename)
if err != nil {
fmt.Println("创建文件失败:", err)
return
}
defer file.Close()
_, err = io.Copy(file, resp.Body)
if err != nil {
fmt.Println("下载文件写入失败:", err)
return
}
fmt.Println("下载文件成功:", filename)
}
func main() {
var wg sync.WaitGroup
urls := []string{
"https://cdn.jsdelivr.net/npm/vue/dist/vue.js",
"https://cdn.jsdelivr.net/npm/react/dist/react.js",
"https://cdn.jsdelivr.net/npm/angular/angular.js",
"https://cdn.jsdelivr.net/npm/jquery/dist/jquery.js",
}
for _, url := range urls {
wg.Add(1)
filename := fmt.Sprintf("download/%s", url[strings.LastIndex(url, "/")+1:])
go downloadFile(url, filename, &wg)
}
wg.Wait()
fmt.Println("所有文件下载完成。")
}
在这个例子中,我们创建了一个包含4个文件URL的数组,使用循环为每个URL都创建一个协程,并将下载的函数和WaitGroup
传递给该协程。每个协程下载完成一个文件后,都会调用wg.Done()
,减少WaitGroup
的计数器的值。最后,主函数会调用wg.Wait()
等待所有协程执行完毕后才输出“所有文件下载完成”的信息。
以上就是使用WaitGroup
实现协程同步的完整攻略,希望对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go并发:使用sync.WaitGroup实现协程同步方式 - Python技术站