Buzz words
Synchronization(同步 )
Race Condition(竞争条件)
Data race(数据竞争)
Mutual exclusion(互斥现象)
Critical section/region(临界区)
Atomic operation(原子操作)
为什么需要同步机制
现代操作系统设计的要点是多进程/线程
-
同步很重要
举个例子,如果你和你的另一半分别从银行取1000,取钱的步骤包括
查询余额,取钱扣钱,更新余额。
那你们可能差不多先都查询到了余额为10000,
各自取了1000,两个ATM机计算出来的余额为9000,
于是ATM机写回了9000
这样的话银行会不开心,但如果换成存钱呢?
---
###Data races
**对共享数据的访问是需要同步的**
分析这个问题时,首先分析有哪些共享的数据。(老师的课件里面的例子中有粉笔和计数器)
- 什么情况下数据会被共享?
- 局部变量是不会被共享的,它是私有的。
>此处的局部变量是指栈上的数据,每个线程有自己的栈,不会出现将一个指向栈上的数据的指针从线程T1传递给线程T2
- 全局变量和静态变量是被共享的
>因为它们都存储在可执行文件的数据段(data segment)中
- 堆上的数据和一些动态对象是被共享的
>虽然每个线程有自己的栈,但这些栈是在进程的栈空间中划出来的。这些栈对线程是私有的,但进程的堆空间是共享的。可以通过指向堆的指针访问。一般这些指针与```new```和```delete```有关。
![回忆进程地址空间(图来自网上)](http://upload-images.jianshu.io/upload_images/4984976-c13ceb7c67f8f4b7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 如何判断是否会发生data races?
- 假设只有读和写是原子的。(**有的架构连这一点都做不到**)
- 假设上下文切换/调度可以发生在任何时候
- 假设你可以无期限地推迟一个线程被调度的时机,甚至可以认为它永远不会调度。
---
### Critical Sections
**我们希望能够通过互斥的方式进行同步**
因为这样我们能够进行更大的原子操作。
- 使用互斥来进行同步的代码段被称为**临界区**
- 一次只能有一个线程进入临界区
- 所有其他的线程都被强制在临界区外等候
- 只有当一个线程离开临界区的时候,另外一个线程才能进入
对临界区应该有什么样的使用原则?
- ```避免竞争的四个条件:```
- 线程的运行速度可以任意变化,CPU的数量可以任意多
- 两个线程不可以同时进入临界区
- 不能有在临界区外的其他线程会阻碍临界区内的线程
- 线程不能永远没有进入临界区的机会
- ```临界区使用的三个原则:```
- 互斥访问(如果Pi在临界区中,则不能有其他任何线程在临界区中)
- 如果没有线程在临界区中,并且有一些线程想要进入临界区,那么只有那些在等待中的线程能够参与关于谁接下来进临界区的决策。而且这个选择不能被无限制地延长。
- 有限等待
那么临界区具体应该怎么实现呢?
- [原子读写操作](http://www.jianshu.com/p/8286b118a294)
- [锁](http://www.jianshu.com/p/59d346bb39fa)
- [信号量](http://www.jianshu.com/p/b855fe91db88)
- [管程]()
- [Messages]()
---