Skip to content

Commit bb1de17

Browse files
add
1 parent 092a4ec commit bb1de17

2 files changed

Lines changed: 19 additions & 25 deletions

File tree

lec12/p1-syncmutex.md

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ flag[i] = IDLE;//结束,自己变idle
700700

701701
---
702702

703-
##### 锁(lock)
703+
##### 锁(TAS lock)
704704
现代CPU提供一些特殊的原子操作指令
705705
- 原子操作指令
706706
- 测试和置位(Test-and-Set )指令
@@ -715,7 +715,7 @@ flag[i] = IDLE;//结束,自己变idle
715715

716716
---
717717

718-
##### 锁(lock)
718+
##### 锁(TAS lock)
719719
现代CPU都提供一些特殊的原子操作指令
720720
```
721721
do {
@@ -730,7 +730,7 @@ do {
730730

731731
---
732732

733-
##### 锁(lock)
733+
##### 锁(TAS lock)
734734
现代CPU都提供一些特殊的原子操作指令
735735
```
736736
do {
@@ -749,7 +749,7 @@ unlock(): lock=false;
749749

750750
---
751751

752-
##### 锁(lock)
752+
##### 锁(CAS lock)
753753
- 原子操作:交换指令CaS(Compare and Swap)
754754
```
755755
bool compare_and_swap(int *value, int old, int new) {
@@ -767,28 +767,10 @@ lock=0; // unlock 解锁
767767
remainder section;
768768
```
769769

770-
<!-- ---
771-
772-
##### 方法3:更高级的抽象方法 -- 锁(lock)
773-
- 原子操作:交换指令CaS(Compare and Swap)
774-
```
775-
bool compare_and_swap(int *value, int old, int new) {
776-
if(*value==old) {
777-
*value = new;
778-
return true;
779-
}
780-
return false;
781-
}
782-
```
783-
```
784-
lock(): while(!compare_and_swap(&lock,0,1));
785-
critical section;
786-
unlock(): lock=0;
787-
``` -->
788770

789771
---
790772

791-
##### 锁(lock)
773+
##### 锁(CAS lock)
792774
<!-- CAS是什么?ABA问题又应该如何理解?https://zhuanlan.zhihu.com/p/139635112
793775
https://www.zhihu.com/question/23281499/answer/24112589
794776
关于ABA问题我想了一个例子:在你非常渴的情况下你发现一个盛满水的杯子,你一饮而尽。之后再给杯子里重新倒满水。然后你离开,当杯子的真正主人回来时看到杯子还是盛满水,他当然不知道是否被人喝完重新倒满。解决这个问题的方案的一个策略是每一次倒水假设有一个自动记录仪记录下,这样主人回来就可以分辨在她离开后是否发生过重新倒满的情况。这也是解决ABA问题目前采用的策略。
@@ -803,7 +785,6 @@ https://www.zhihu.com/question/23281499/answer/24112589
803785
- 解决思路:加上版本号(时间戳)
804786
- (100,1); (50,2); (100,3)
805787
<!---
806-
807788
##### 方法3:更高级的抽象方法 -- 锁(lock)
808789
现代CPU体系结构都提供一些特殊的原子操作指令
809790
- 原子操作指令
@@ -815,6 +796,17 @@ https://www.zhihu.com/question/23281499/answer/24112589
815796

816797
---
817798

799+
##### TAS vs CAS
800+
801+
|维度 | TAS(Test-and-Set)| CAS(Compare-and-Swap)|
802+
|---|---|---|
803+
|缓存友好度 | 较差,多核缓存竞争 | 较好,有效减少总线无效流量
804+
|竞争性能 | 低竞争表现尚可,高竞争性能下滑明显 | 高并发竞争场景性能更优异|
805+
|适用场景 |基础简易自旋锁 |自旋锁、无锁数据结构、内核同步机制等|
806+
|ABA 问题 | 不存在该问题 |存在 ABA 隐患,需版本号等手段规避|
807+
808+
---
809+
818810
##### 锁(lock)
819811
使用TaS指令实现自旋锁(spinlock)
820812
- 线程在等待的时候消耗CPU时间

lec12/p6-labs.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ time cost is 919ms
317317

318318
#### 程序设计
319319
spin mutex和 block mutex 的核心数据结构(**全局变量**): `UPSafeCell`
320+
UPSafeCell 是锁的数据容器,利用 RefCell 的借用检查机制,在锁保证互斥的前提下,让内核可以安全、方便地修改全局可变状态,。
320321
```rust
321322
pub struct UPSafeCell<T> { //允许在单核上安全**使用可变全局变量**
322323
inner: RefCell<T>, //提供内部可变性和运行时借用检查
@@ -376,12 +377,13 @@ impl Mutex for MutexSpin {
376377
loop {
377378
let mut locked = self.locked.exclusive_access(); //独占访问locked
378379
if *locked {
379-
drop(locked);
380+
drop(locked);//主动释放对内部数据的借用,放弃对 self.locked 所保护数据的独占
380381
suspend_current_and_run_next(); //把当前线程放到就绪队列末尾
381382
continue;
382383
} else {
383384
*locked = true; //得到锁了,可以继续进入临界区执行
384385
return;
386+
}
385387
...
386388
```
387389

0 commit comments

Comments
 (0)