只执行一次初始化,注意协程的公共变量与私有变量。
-
// sync_my project main.go
-
package main
-
-
import (
-
"fmt"
-
"sync"
-
"time"
-
)
-
-
func ExampleOnce() {
-
var once sync.Once
-
onceBody := func() {
-
fmt.Println("Only once")
-
}
-
done := make(chan bool)
-
for i := 0; i < 10; i++ {
-
go func(j int) {
-
once.Do(onceBody)
-
done <- true
-
fmt.Printf("routinei: %d put\n", i)
-
fmt.Printf("routinej: %d put\n", j)
-
}(i)
-
}
-
for i := 0; i < 10; i++ {
-
<-done
-
fmt.Printf("main get %d\n", i)
-
}
-
// Output:
-
// Only once
-
}
-
-
func main() {
-
ExampleOnce()
-
time.Sleep(2)
-
}
结果输出:
Only once
routinei: 10 put
routinej: 9 put
main get 0
main get 1
main get 2
main get 3
main get 4
main get 5
main get 6
main get 7
main get 8
main get 9
routinei: 10 put
routinej: 4 put
routinei: 10 put
routinej: 6 put
routinei: 10 put
routinej: 1 put
routinei: 10 put
routinei: 10 put
routinej: 5 put
routinei: 10 put
routinej: 3 put
routinei: 10 put
routinej: 2 put
routinei: 10 put
routinej: 7 put
routinej: 0 put
routinei: 10 put
routinej: 8 put
成功: 进程退出代码 0.
---------------------------------------------------
注释:
1.函数onceBody只执行1次
2.为了确保所有协程都执行完,主线程才退出,在主线程最后休眠2秒。
3.i是公共变量,由于cpu操作比io快很多,所有最后i变成10了,语句fmt.Printf("routinei: %d put\n", i)才执行,所以协程输出i都是10。j是协程私有变量,输出传给各个协程的编号,各个协程互不影响。
阅读(518) | 评论(0) | 转发(0) |