Go语言核心36讲
郝林
《Go并发编程实战》作者,前轻松筹大数据负责人
立即订阅
24066 人已学习
课程目录
已完结 54 讲
0/4登录后,你可以任选4讲全文学习。
开篇词+学习路线 (3讲)
开篇词 | 跟着学,你也能成为Go语言高手
免费
预习篇 | 写给0基础入门的Go语言学习者
50 | 学习专栏的正确姿势
模块一:Go语言基础知识 (6讲)
01 | 工作区和GOPATH
02 | 命令源码文件
03 | 库源码文件
04 | 程序实体的那些事儿(上)
05 | 程序实体的那些事儿(中)
06 | 程序实体的那些事儿 (下)
模块二:Go语言进阶技术 (16讲)
07 | 数组和切片
08 | container包中的那些容器
09 | 字典的操作和约束
10 | 通道的基本操作
11 | 通道的高级玩法
12 | 使用函数的正确姿势
13 | 结构体及其方法的使用法门
14 | 接口类型的合理运用
15 | 关于指针的有限操作
16 | go语句及其执行规则(上)
17 | go语句及其执行规则(下)
18 | if语句、for语句和switch语句
19 | 错误处理(上)
20 | 错误处理 (下)
21 | panic函数、recover函数以及defer语句 (上)
22 | panic函数、recover函数以及defer语句(下)
模块三:Go语言实战与应用 (27讲)
23 | 测试的基本规则和流程 (上)
24 | 测试的基本规则和流程(下)
25 | 更多的测试手法
26 | sync.Mutex与sync.RWMutex
27 | 条件变量sync.Cond (上)
28 | 条件变量sync.Cond (下)
29 | 原子操作(上)
30 | 原子操作(下)
31 | sync.WaitGroup和sync.Once
32 | context.Context类型
33 | 临时对象池sync.Pool
34 | 并发安全字典sync.Map (上)
35 | 并发安全字典sync.Map (下)
36 | unicode与字符编码
37 | strings包与字符串操作
38 | bytes包与字节串操作(上)
39 | bytes包与字节串操作(下)
40 | io包中的接口和工具 (上)
41 | io包中的接口和工具 (下)
42 | bufio包中的数据类型 (上)
43 | bufio包中的数据类型(下)
44 | 使用os包中的API (上)
45 | 使用os包中的API (下)
46 | 访问网络服务
47 | 基于HTTP协议的网络服务
48 | 程序性能分析基础(上)
49 | 程序性能分析基础(下)
尾声与思考题答案 (2讲)
尾声 | 愿你披荆斩棘,所向无敌
新年彩蛋 | 完整版思考题答案
Go语言核心36讲
登录|注册

26 | sync.Mutex与sync.RWMutex

郝林 2018-10-10
我在前面用 20 多篇文章,为你详细地剖析了 Go 语言本身的一些东西,这包括了基础概念、重要语法、高级数据类型、特色语句、测试方案等等。
这些都是 Go 语言为我们提供的最核心的技术。我想,这已经足够让你对 Go 语言有一个比较深刻的理解了。
从本篇文章开始,我们将一起探讨 Go 语言自带标准库中一些比较核心的代码包。这会涉及这些代码包的标准用法、使用禁忌、背后原理以及周边的知识。
既然 Go 语言是以独特的并发编程模型傲视群雄的语言,那么我们就先来学习与并发编程关系最紧密的代码包。

前导内容: 竞态条件、临界区与同步工具

我们首先要看的就是sync包。这里的“sync”的中文意思是“同步”。我们下面就从同步讲起。
相比于 Go 语言宣扬的“用通讯的方式共享数据”,通过共享数据的方式来传递信息和协调线程运行的做法其实更加主流,毕竟大多数的现代编程语言,都是用后一种方式作为并发编程的解决方案的(这种方案的历史非常悠久,恐怕可以追溯到上个世纪多进程编程时代伊始了)。
一旦数据被多个线程共享,那么就很可能会产生争用和冲突的情况。这种情况也被称为竞态条件(race condition),这往往会破坏共享数据的一致性。
共享数据的一致性代表着某种约定,即:多个线程对共享数据的操作总是可以达到它们各自预期的效果。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Go语言核心36讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(21)

  • 属鱼
    第一个问题:
    Lock接口。
    第二个问题:
    变量.Rlock()
    2018-10-10
    14
  • Geek_cd5dcf
    讲的通俗易懂,还是挺好理解的,想问下mutex如果加锁后
    mutex.lock()
    defer mutex.unlock()
    在所有场景下都不会出错吗?

    作者回复: 对,不会,这是defer的机制保证的。

    2018-10-11
    1
    8
  • 🤔
    1. Locker 接口
    2. func (rw *RWMutex) RLocker() Locker

    作者回复: √

    2019-03-16
    6
  • sky
    郝大 关于demo59这个案例能大概描述下具体的功能流程吗 代码看起来没有方向感啊
    2018-10-22
    1
    3
  • Hector
    读写锁总结,1、可以随便读,即使加锁多个goroutine同时读 2、加锁写的时候,啥也不能干,不能写。即使没加读锁也不能读。老师写的有点绕蒙了。
    引用原文:对写锁进行解锁,会唤醒“所有因试图锁定读锁,而被阻塞的 goroutine”,并且,这通常会使它们都成功完成对读锁的锁定。意思就是在对资源的写锁进行解锁时,原来你在对该资源上写锁的时候,所有的读锁会锁定来配合写操作,直到写锁解除锁定时,这些读锁才会解锁。
    2019-05-16
    1
    2
  • 阳仔
    学习将近一半的课程了发现:
    1. 内容不够简洁,很多知识点其实画图出来更容易让读者理解
    2. 感觉不大适合初学者,反而对已经入门有一定经验的学习者会帮助更大一些
    3. 可以看出来作者是非常精通go的
    2019-04-03
    2
  • Leon📷
    老师,我想问下多协程并发情况怎么调试日志,google官方似乎也不推荐我们在日志中把协程号打印出来,只能通过添加唯一序列号识别吗
    2018-11-13
    1
    2
  • jacke
    问下老师,读写锁解锁部分有点不明白:写锁解锁的时候如果同时有写锁和读锁在等待,是优先唤醒读锁是把?
    这个规定对读锁解锁也适用是把?
    2018-11-07
    1
  • timmy21
    郝老师,之前问了一个是否需要上锁的问题。有一个细节我忘说了,一个写者,一个读者,并且“读者”读取变量时不需要保证返回最新值。这种场景下是否可以不上锁?或者不上锁会有什么问题吗?会panic吗?
    2018-10-15
    2
    1
  • 疯琴
    讲得挺清晰的
    2019-11-25
  • 安排
    goroutine和协程有什么本质区别啊,搜了网上也没看出来啥本质区别,有这方面的资料吗?

    作者回复: 传统的协程只是线程内的流程控制工具。它没法做到一个线程内有两个及以上控制流同时进行,只能是这一个挂起那一个运行然后那一个挂起这一个再运行。同时它也不属于多线程编程,没法统一调度多个线程内的控制流。

    goroutine 我就不用多说了,它属于用户级线程,与系统级线程搭配使用,很强大也很灵活。深入的东西可以看我的那本《Go 并发编程实战》。

    2019-09-22
  • 大王叫我来巡山
    需要请教老师的是,主协程收到信号就被唤醒了,认为可以读了,但是被阻塞的写协程收到锁释放的消息会不会比主协程要早,然后继续获得写的机会,主协程会不会被阻塞?我认为是不会的,此处的锁只是保证了不同写协程互斥的写入,也就是写操作是原子的,但是并不保证读操作一定在写完后就读吧

    作者回复: 对于非缓冲通道,写的 goroutine 必然会先完成操作。锁本身只保证互斥。被阻塞的 goroutine 也会有先有后,但会根据被阻塞那一刻的先后,而不是什么读写的先后。

    另外互斥锁跟原子操作有本质上的区别,不要搞混。

    再另外,goroutine 与协程也有本质上的区别,不要搞混。

    2019-09-13
    1
  • 芝士老爹
    如果一直有新的读锁请求,会不会导致写锁锁不了?
    还是说如果有了一个wlock锁请求了,现在因为有rlock未释放锁,wlock的协程被阻塞,后面再有新的rlock锁请求也会先被阻塞,等待wlock锁协程先恢复?

    作者回复: 那要看谁先等待了,这里的等待队列是先进先出的。

    2019-08-04
    2
  • 糊李糊涂
    Locker和RLocker
    2019-06-12
  • soooldier
    配套代码里puzzlers/article26下并没有demo58.go,也没有demo59.go,懵圈中。。。

    作者回复: 看这里吧:https://github.com/hyper0x/Golang_Puzzlers/tree/master/src/puzzlers/article22

    你可以把这里的 article 理解成 topic。一些比较长的 topic 可能会被编辑拆分为多篇文章,所以就出现了这种情况。太长的文章对读者们不太友好,不容易集中精力读下去。

    你可以对照着专栏的目录,按照主题,找一下对应的 articleXX 目录。

    Update:
    我刚刚添加了一个序号映射表:https://github.com/hyper0x/Golang_Puzzlers/blob/master/mapping_table.md 。你用这个就可以方便地对照了。

    2019-05-31
  • 张sir
    一组临界区是什么场景下会,能举个例子吗?

    作者回复: 你可以理解为同一把锁保护的多个代码段。

    2019-05-05
  • ...
    老师 go有没有可重入锁的概念

    作者回复: 这里说的就是可重入锁啊。

    2019-02-20
    2
  • 静以储势·Shuke
    Golang可以用mutex像java一样嵌套加锁么?
    2018-12-05
    2
  • 生活在别处
    读写锁是公平的吗?
    2018-11-15
  • timmy21
    郝老师,我使用race进行竞争检测,发现有些变量只有一个写者,一个读者。程序运行没有问题,上锁我担心性能下降,这种情况下需要去上锁吗?

    作者回复: 必须上锁,程序现在运行没问题不代表到服务器上没问题。

    2018-10-11
收起评论
21
返回
顶部