在使用sync.WaitGroup
进行并发编程时,panic
通常是由于以下几个原因造成的:
WaitGroup
之前已经调用了Add
方法来设置计数器。Done
方法来减少计数器。panic
。Wait
方法调用之后,不应该再有其他可能阻塞的操作,否则可能会导致死锁。以下是一个使用sync.WaitGroup
进行WebCrawl的示例代码,展示了如何正确使用WaitGroup
以避免panic
:
package main
import (
"fmt"
"net/http"
"sync"
)
func crawl(url string, wg *sync.WaitGroup) {
defer wg.Done() // 确保在函数返回前调用Done
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
// 处理网页内容...
fmt.Println("Crawled", url)
}
func main() {
var wg sync.WaitGroup
urls := []string{
"http://example.com",
"http://example.org",
"http://example.net",
}
for _, url := range urls {
wg.Add(1) // 在启动goroutine之前调用Add
go crawl(url, &wg)
}
wg.Wait() // 等待所有goroutine完成
fmt.Println("Crawling finished")
}
main
函数中初始化sync.WaitGroup
。wg.Add(1)
来增加计数器。defer wg.Done()
来确保计数器在函数返回前减少。main
函数中调用wg.Wait()
来等待所有goroutine完成。通过遵循这些最佳实践,可以有效地避免在使用sync.WaitGroup
时出现panic
的情况。
领取专属 10元无门槛券
手把手带您无忧上云