036_go语言中的原子计数器
代码演示
package main import ( "fmt" "runtime" "sync/atomic" "time" ) func main() { var ops uint64 = 0 for i := 0; i < 50; i++ { go func() { for { atomic.AddUint64(&ops, 1) runtime.Gosched() } }() } time.Sleep(time.Second) opsFinal := atomic.LoadUint64(&ops) fmt.Println("ops:", opsFinal) }
代码运行结果
ops: 7838509
代码解读
- go语言中最主要的状态管理方式是通过通道间的沟通完成的,本例子中,我们用sync/atomic包在多个go协程中进行原子计数
- 先定义一个ops为无符号整形(永远是正整数),然后启动50个协程,对计数器每隔一定时间进行加一的操作
- 使用&来读取ops的内存地址,这样可以修改原来的值,不会拷贝新值
- runtime.Gosched()的作用是,可以由其它的协程继续执行。比如第一个协程for循环执行到这里,由第二个协程可以接力过来继续执行
- 最后等待1秒钟,留给协程足够的时间执行,最终读取了计数器的值