协程并发
Go 语言支持并发,只需要通过 go 关键字开启协程 goroutine 即可 goroutine 是轻量级线程,它的调度是由 Golang 程序运行时进行管理的 每一个 goroutine 执行一个函数,同一个程序中的所有 goroutine 共享同一个地址空间
goroutine 语法格式如下
go 函数名 ( 参数列表 )
go f (x, y, z)
sleep
// 睡眠1秒,等待上面两个协程结束
func say (s string) {
for i := 0; i <= 5; i++ {
fmt.Println(s)
}
}
func main () {
go say("world")
say("hello")
var ss = "golang"
go func (s string) {
for i := 0; i <= 5; i++ {
fmt.Println(s)
}
}(ss)
time.Sleep(time.Second * 1)
}
sync.WaitGroup
// 使用 sync.WaitGroup,等待上面两个协程结束
func say (s string, wg *sync.WaitGroup) {
defer wg.Done() // 操作完成,减少一个计数
for i := 0; i <= 5; i++ {
fmt.Println(s)
}
}
func main () {
var wg sync.WaitGroup
wg.Add(2) // 因为有两个动作,所以增加2个计数
go say("world", &wg)
var ss = "golang"
go func (s string) {
defer wg.Done() // 操作完成,减少一个计数
for i := 0; i <= 5; i++ {
fmt.Println(s)
}
}(ss)
wg.Wait() // 等待,直到计数为0
}
channel
// 使用通道,等待上面两个协程结束
func main () {
ch := make(chan struct{})
count := 2 // count 表示活动的协程个数
go func () {
fmt.Println(123)
ch <- struct{}{} // 协程结束,发出信号
}
go func () {
fmt.Println(456)
ch <- struct{}{} // 协程结束,发出信号
}
for range ch {
// 每次从 ch 中接收数据,表示一个活动的协程结束
count--
// 当所有活动的协程都结束时,关闭通道
if count == 0 {
close(ch)
}
}
}