1 关键字go和channel实现并发(阻塞主进程,防止其退出)
go语言,语言层面原生支持高并发,通过关键字go与信号通道channel组合实现。实现起来还是相当容易的例如:
package main
import (
"fmt"
)
func main() {
c := make(chan bool, 100)
for i := 0; i < 100; i++ {
go func(i int) {
fmt.Println(i)
c <- true
}(i)
}
for i := 0; i < 100; i++ {
<-c
}
}
2 通过sync.WaitGroup
除了关键字go和channel,我们还有更简单的方法来实现,就是标准库sync中的WaitGrop
WaitGroup等待一组goroutines完成。主goroutine调用Add来设置要等待的goroutine的数量。然后每个goroutines运行并在完成时调用Done。同时,Wait可以用来阻塞,直到所有goroutines完成。
WaitGroup在第一次使用后不能被复制。
package main
import (
"fmt"
"sync"
)
func main() {
wg := sync.WaitGroup{}
wg.Add(10)
for i := 0; i < 10; i++ {
go func(i int) {
fmt.Println(i)
wg.Done()
}(i)
}
wg.Wait()
}
WaitGroup 结构:
type WaitGroup struct {
// contains filtered or unexported fields
}
我们来看看官网的例子:
package main
import (
"sync"
)
type httpPkg struct{}
func (httpPkg) Get(url string) {}
var http httpPkg
func main() {
var wg sync.WaitGroup
var urls = []string{
"http://www.golang.org/",
"http://www.google.com/",
"http://www.example.com/",
}
for _, url := range urls {
// Increment the WaitGroup counter.
wg.Add(1)
// Launch a goroutine to fetch the URL.
go func(url string) {
// Decrement the counter when the goroutine completes.
defer wg.Done()
// Fetch the URL.
http.Get(url)
}(url)
}
// Wait for all HTTP fetches to complete.
wg.Wait()
}