golang中有2种方式同步程序,一种使用channel,另一种使用锁机制。sync.WaitGroup只有3个方法,Add(),Done(),Wait()。其中Done()是Add(-1)的别名。简单的来说,使用Add()添加计数,Done()减掉一个计数,计数不为0, 阻塞Wait()的运行。
func main(){
go foo()
go bar()
}
func foo(){
for i := 0; i < 45; i++{
fmt.Println("Foo",i)
}
}
func bar(){
for i := 0; i < 45; i++{
fmt.Println("Bar:",i)
}
}
var wg sync.WaitGroup
func main(){
wg.Add(2)
go foo()
go bar()
wg.Wait()
}
func foo(){
for i := 0; i < 45; i++{
fmt.Println("Foo",i)
}
wg.Done()
}
func bar(){
for i := 0; i < 45; i++{
fmt.Println("Bar:",i)
}
wg.Done()
}
waitGroup 添加 2 两个然后直到执行到 0 ,排序是不确定,这里复习一下接口引用的调用方式。
func (wg *WaitGroup) Add(delta int)
package main
import(
"fmt"
"math"
)
type circle struct{
radius float64
}
type shape interface{
area() float64
}
func (c *circle) area() float64{
return math.Pi * c.radius * c.radius
}
func info(s shape){
fmt.Println("area",s.area())
}
func main() {
c := circle{5}
info(c)
}
circle does not implement shape (area method has pointer receiver)
func main() {
c := &circle{5}
info(c)
}
在 go 语言中可以为一个常量 42 定义时候指定类型或者不指定类型。在定义类型时候在 go 语言还不确定是否分配内存,所以在接受指针类型的情况我们不能使用值传递。
func foo(){
for i := 0; i < 45; i++{
fmt.Println("Foo",i)
time.Sleep(time.Duration(3.*time.Millisecond))
}
wg.Done()
}
func bar(){
for i := 0; i < 45; i++{
fmt.Println("Bar:",i)
time.Sleep(time.Duration(20.*time.Millisecond))
}
wg.Done()
}
加入休眠,当任务休眠时候,空闲下来 CPU 就可以去处理其他任务。
从图可以清晰地看出 concurrency 和 parallelism 的区别,一个恰当实例就是我们喝咖啡和谈话,concurrency 就是类似我们一边和咖啡一边打电话。类似同时进行,切实是在两者之间不断切换。
有疑问加站长微信联系(非本文作者)