Fix typo in sync1.md

pull/289/head
lijinpeng 3 years ago
parent fe98590886
commit 5007f82840

@ -248,7 +248,7 @@ fn main() {
在上面的描述中,我们用了"可能"二字,原因在于死锁在这段代码中不是必然发生的,总有一次运行你能看到最后一行打印输出。这是由于子线程的初始化顺序和执行速度并不确定,我们无法确定哪个线程中的锁先被执行,因此也无法确定两个线程对锁的具体使用顺序。 在上面的描述中,我们用了"可能"二字,原因在于死锁在这段代码中不是必然发生的,总有一次运行你能看到最后一行打印输出。这是由于子线程的初始化顺序和执行速度并不确定,我们无法确定哪个线程中的锁先被执行,因此也无法确定两个线程对锁的具体使用顺序。
但是可以简单的说明下死锁发生的必然条件线程1锁住了`mutex1`并且线程`2`锁住了`mutex2`然后线程1试图去访问`mutex2`,同时线程`2`试图去访问`mutex1`,就会锁。 因为线程2需要等待线程1释放`mutex1`后,才会释放`mutex2`而与此同时线程1需要等待线程2释放`mutex2`后才能释放`mutex1`,这种情况造成了两个线程都无法释放对方需要的锁,最终死。 但是可以简单的说明下死锁发生的必然条件线程1锁住了`mutex1`并且线程`2`锁住了`mutex2`然后线程1试图去访问`mutex2`,同时线程`2`试图去访问`mutex1`,就会锁。 因为线程2需要等待线程1释放`mutex1`后,才会释放`mutex2`而与此同时线程1需要等待线程2释放`mutex2`后才能释放`mutex1`,这种情况造成了两个线程都无法释放对方需要的锁,最终死
那么为何某些时候死锁不会发生原因很简单线程2在线程1锁`mutex1`之前就已经全部执行完了随之线程2的`mutex2`和`mutex1`被全部释放线程1对锁的获取将不再有竞争者。 同理线程1若全部被执行完那线程2也不会被锁因此我们在线程1中间加一个睡眠增加死锁发生的概率。如果你在线程2中同样的位置也增加一个睡眠那死锁将必然发生! 那么为何某些时候死锁不会发生原因很简单线程2在线程1锁`mutex1`之前就已经全部执行完了随之线程2的`mutex2`和`mutex1`被全部释放线程1对锁的获取将不再有竞争者。 同理线程1若全部被执行完那线程2也不会被锁因此我们在线程1中间加一个睡眠增加死锁发生的概率。如果你在线程2中同样的位置也增加一个睡眠那死锁将必然发生!
@ -307,7 +307,7 @@ fn main() {
} }
``` ```
为了演示`try_lock`的作用,我们特定使用了之前必定会死锁的代码,并且将`lock`替换`try_lock`,与之前的结果不同,这段代码将不会再有死锁发生: 为了演示`try_lock`的作用,我们特定使用了之前必定会死锁的代码,并且将`lock`替换`try_lock`,与之前的结果不同,这段代码将不会再有死锁发生:
```console ```console
线程 0 锁住了mutex1接着准备去锁mutex2 ! 线程 0 锁住了mutex1接着准备去锁mutex2 !
线程 1 锁住了mutex2, 准备去锁mutex1 线程 1 锁住了mutex2, 准备去锁mutex1
@ -396,7 +396,7 @@ Err("WouldBlock")
如果不是追求特别极致的性能,建议选择前者。 如果不是追求特别极致的性能,建议选择前者。
## 用条件(Condvar)控制线程的同步 ## 用条件变量(Condvar)控制线程的同步
`Mutex`用于解决资源安全访问的问题但是我们还需要一个手段来解决资源访问顺序的问题。而Rust考虑到了这一点为我们提供了条件变量(Condition Variables),它经常和`Mutex`一起使用,可以让线程挂起,直到某个条件发生后再继续执行,其实`Condvar`我们在之前的多线程章节就已经见到过,现在再来看一个不同的例子: `Mutex`用于解决资源安全访问的问题但是我们还需要一个手段来解决资源访问顺序的问题。而Rust考虑到了这一点为我们提供了条件变量(Condition Variables),它经常和`Mutex`一起使用,可以让线程挂起,直到某个条件发生后再继续执行,其实`Condvar`我们在之前的多线程章节就已经见到过,现在再来看一个不同的例子:
@ -474,7 +474,7 @@ async fn main() {
let mut join_handles = Vec::new(); let mut join_handles = Vec::new();
for _ in 0..5 { for _ in 0..5 {
let permit = semaphore.clone().acquire_owned().await.unwrap(); let permit = semaphore.clone().acquire_owned().await.unwrap();
join_handles.push(tokio::spawn(async move { join_handles.push(tokio::spawn(async move {
// //
// 在这里执行任务... // 在这里执行任务...

Loading…
Cancel
Save