在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Golang推荐通过channel 进行通信和同步,但在实际开发中sync包用的也较多;另外sync下还有一个atomic包,提供了一些底层的原子操作。
原子操作atomic atomic包(sync/atomic)提供了底层的原子级内存操作。
共有五种操作:增减, 比较并交换, 载入, 存储,交换(T代表int32、int64、uint32、uint64、unitptr、pointer(没有增减操作))
示例程序 var sum uint32 = 100 atomic.CompareAndSwapUint32(&sum, 100, sum+1) // 101 atomic.CompareAndSwapUint32(&sum, 100, sum+1) // 101,不等没有变化 atomic.AddUint32(&sum, 1) // 102
互斥锁 互斥锁用来保证在任一时刻,只能有一个例程访问某对象。Mutex 的初始值为解锁状态。Mutex 通常作为其它结构体的匿名字段使用,使该结构体具有 Lock 和 Unlock 方法。
相关函数
锁相关主要操作接口 type Locker interface { Lock() Unlock() }
读写互斥锁 RWMutex 比 Mutex 多了一个“读锁定”和“读解锁”,可以让多个例程同时读取某对象。RWMutex 的初始值为解锁状态。RWMutex 通常作为其它结构体的匿名字段使用。
相关函数
组等待 WaitGroup 用于等待一组例程的结束。主例程在创建每个子例程的时候先调用 Add 增加等待计数,每个子例程在结束时调用 Done 减少例程计数。之后,主例程通过 Wait 方法开始等待,直到计数器归零才继续执行。
相关函数
示例程序 wg := sync.WaitGroup{} for i := 0; i < 10; i++ { wg.Add(1) // 进入例程前调用,也可在循环外直接加10 go func(i int) { defer wg.Done() fmt.Print(i, " ") }(i) } wg.Wait()
条件等待 Cond条件变量是线程间共享的一种机制,主要包括两个动作:
相关函数
示例:条件等待 condition := false // 条件 var mu sync.Mutex cond := sync.NewCond(&mu) // 唤醒者 go func() { time.Sleep(...) mu.Lock() condition = true // 更改条件 cond.Signal() // 发送通知:条件已经满足 mu.Unlock() }() // 等待者 go func() { mu.Lock() // 检查条件是否满足,避免虚假通知,同时避免 Signal 提前于 Wait 执行。 for !condition { cond.Wait() // 等待时 mu 处于解锁状态,唤醒时重新锁定。 } ... mu.Unlock() }
单次执行 Once 的作用是多次调用但只执行一次。Once 只有一个方法Do(),向 Do 传入一个函数,这个函数在第一次执行 Once.Do() 的时候会被调用,以后再执行 Once.Do() 将没有任何动作,即使传入了其它的函数,也不会被执行,如果要执行其它函数,需要重新创建一个 Once 对象。 Once 可以安全的在多个例程中并行使用。
相关函数
临时对象池 sync.Pool对象就是一组临时对象的集合。用于存储那些被分配了但是没有被使用,而未来可能会使用的值(放进Pool中的对象,会随时被回收掉;所以如果事先Put进去100个对象,下次Get的时候发现Pool是空也是有可能的),以减小垃圾回收的压力。 Pool是协程安全的。
相关函数
示例程序 var bytePool = sync.Pool{ New: func() interface{} { b := make([]byte, 1024) return &b }, }
for i := 0; i < 10000; i++{ obj := bytePool.Get().(*[]byte) _ = obj ... bytePool.Put(obj) }
安全map 为解决map并发读写问题,引入了sync.map。sync.map针对相对稳定的key(读多、写少情况)做了优化,若是频繁的读写则使用内置map与RWMutex更好。
主要函数
示例程序 var m sync.Map vv, ok := m.LoadOrStore("1", "one") fmt.Println(vv, ok) //one false vv, ok = m.Load("1") fmt.Println(vv, ok) //one true vv, ok = m.LoadOrStore("1", "oneone") fmt.Println(vv, ok) //one true m.Store("1", "oneone") vv, ok = m.Load("1") fmt.Println(vv, ok) // oneone true m.Store("2", "two") m.Range(func(k, v interface{}) bool { fmt.Println(k, v) return true }) m.Delete("1") |
请发表评论