本文最后更新于:2023年11月8日 中午
golang并发编程示例小记
Go提供了sync和channel两种方式来支持协程的并发
0x00 sync
如果我们希望并发下载N个资源,多个并发协程之间不需要通信,那么就可以使用sync.WaitGroup,等待所有并发协程执行结束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package main
import ( "fmt" "sync" "time" )
var wg sync.WaitGroup
func download(url string){ fmt.Println("start downloading:", url) time.Sleep(time.Second) fmt.Println(url + "OK!") wg.Done() }
func main(){ for i := 0;i<10;i++{ wg.Add(1) go download("a.com/" + string(i+'0')) } fmt.Println("waiting...") wg.Wait() fmt.Println("Done!") }
|
- wg.Add(1)表示为wg添加一个计数,wg.Done()减去一个计数
- go download()表示启动新的协程并发执行download函数
- wg.Wait()等待所有协程执行结束
可以看到原来需要10s的并发操作,并发后约1-2s即可执行完毕
0x01 channel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| package main
import ( "fmt" "sync" "time" )
var wg sync.WaitGroup
var ch = make(chan string, 10)
func download(url string){ fmt.Println("start downloading:", url) time.Sleep(time.Second) fmt.Println(url + " OK!") ch <- url }
func main(){ for i := 0;i<10;i++{ go download("a.com/" + string(i+'0')) } for i:=0;i<10;i++{ msg:=<-ch fmt.Println("finish: ", msg) } fmt.Println("Done!") }
|
使用channel信道,可以在协程之间传递消息,阻塞等待并发协程返回消息