Go:线程安全介绍

1. 现实例子

           A. 多个goroutine同时操作一个资源,这个资源又叫临界区

           B. 现实生活中的十字路口,通过红路灯实现线程安全

           C. 火车上的厕所,通过互斥锁来实现线程安全

2. 实际例子, x = x +1

           A. 先从内存中取出x的值

           B. CPU进行计算,x+1

           C. 然后把x+1的结果存储在内存中

3. 互斥锁介绍

           A. 同时有且只有一个线程进入临界区,其他的线程则在等待锁

           B. 当互斥锁释放之后,等待锁的线程才可以获取锁进入临界区

           C. 多个线程同时等待同一个锁,唤醒的策略是随机的

例:有问题的代码!

package main
import (
    "fmt"
    "sync"
)

var x = 0

func increment(wg *sync.WaitGroup) {
    x = x + 1
    wg.Done()
}
func main() {
    var w sync.WaitGroup
    for i := 0; i < 1000; i++ {
    w.Add(1)
    go increment(&w)
    }
    w.Wait()
    fmt.Println("final value of x", x)
}

使用互斥锁fix

package main
import (
    "fmt"
    "sync"
)
var x = 0
func increment(wg *sync.WaitGroup, m *sync.Mutex) {
    m.Lock()
    x = x + 1
    m.Unlock()
    wg.Done()
}
func main() {
    var w sync.WaitGroup
    var m sync.Mutex
    for i := 0; i < 1000; i++ {
        w.Add(1)
        go increment(&w, &m)
    }
    w.Wait()
    fmt.Println("final value of x", x)
}

4. 读写锁使用场景

           A. 读多写少的场景

           B. 分为两种角色,读锁和写锁

           C. 当一个goroutine获取写锁之后,其他的goroutine获取写锁或读锁都会等待

           D. 当一个goroutine获取读锁之后,其他的goroutine获取写锁都会等待, 但其他 goroutine获取读锁时,都会继续获得锁.

5.读写锁案例演示

6. 原子操作 

           A. 加锁代价比较耗时,需要上下文切换

           B. 针对基本数据类型,可以使用原子操作保证线程安全

           C. 原子操作在用户态就可以完成,因此性能比互斥锁要高

7.原子操作介绍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值