1、简单的使用关键字 go + 函数调用实现并发
示例1:
func taskA(){
fmt.Println("A")
}
func taskB(){
fmt.Println("B")
}
func main(){
fmt.Println(time.Now())
go taskA()
go taskB()
fmt.Println(time.Now())
}
结果:
空
结果为空原因:主例程退出,子例程也会退出,即使工作例程没有执行完。
以上代码一种最简单,但比较low的解决方法是使用time.Sleep()
;这种方式可以用于测试,但不能用于实际的应用编写。如下:
func taskA(){
fmt.Println("A")
}
func taskB(){
fmt.Println("B")
}
func main(){
fmt.Println(time.Now())
go taskA()
go taskB()
fmt.Println(time.Now())
time.Sleep(time.Microsecond * 1000)
}
2、runtime包
可以使用runtime包中的Gosched()
方法让函数调用,让出cpu调度给其他例程使用。
示例:
import "runtime"
func taskA(){
for i:=1 ;i<=10;i++{}
fmt.Println("A")
runtime.Gosched()
}
}
func taskB(){
for i:=1;i<=10;i++{}
fmt.Println("B")
runtime.Gosched()
}
}
func main(){
fmt.Println(time.Now())
go taskA()
go taskB()
fmt.Println(time.Now())
time.Sleep(time.Microsecond * 1000)
}
结果,为函数taskA和函数TaskB,穿插这着执行
3、waitgroup,例程间通信(计数信号量)
例程计数信号量:
启动例程之前,信号量+1
当例程执行结束时,信号量-1
当信号量非阻塞主例程结束,当信号量为0时主例程结束。
我们可以”sync”包的 waitgroup 来实现这一功能
示例:
package main
import (
"fmt"
"runtime"
"sync"
)
func taskA(a *sync.WaitGroup){
for i :=0;i<=10;i++{
fmt.Println(i)
runtime.Gosched()
}
a.Done() //或 defer a.Done()
}
func taskB(a *sync.WaitGroup){
for i :=0;i<=10;i++{
fmt.Println(i)
runtime.Gosched()
}
a.Done() //或 defer a.Done()
}
func main(){
fmt.Println("start")
//sync.WaitGroup 是一个结构体,这个结构体只有三个方法 “Add” “Done” “Wait”
//Add 信号量+1
//Done 信号量-1
//wait 信号量为0,允许结束主例程
var wg sync.WaitGroup
go taskA(*wg)
go taskB(*wg)
wg.Wait()
fmt.Println("end")
}
文档更新时间: 2021-08-21 14:26 作者:张尚