package main
import (
"fmt"
"time"
)
// 由于 x=x+1 不是原子操作
// 所以应避免多个协程对x进行操作
// 使用容量为1的信道可以达到锁的效果
func increment(ch chan bool, x *int) {
ch <- true //①
*x = *x + 1
<- ch //②
}
func main() {
// 注意要设置容量为 1 的缓冲信道
pipline := make(chan bool, 1)
var x int
for i:=0;i<1000;i++{
go increment(pipline, &x)
}
// 确保所有的协程都已完成
// 以后会介绍一种更合适的方法(Mutex),这里暂时使用sleep
time.Sleep(3) //③
fmt.Println("x 的值:", x)
}
上述示例中,同时将①②注释掉,会发现x的值会小于1000;此时③的值无论怎么设置x的值最多=1000,但多数情况下x的值会小于1000。
这应该算是通道在协程中应用的最典型的例子。
|