Skip to content

Commit 12ed38b

Browse files
committed
add chapter 05
1 parent b07bece commit 12ed38b

File tree

12 files changed

+152
-4
lines changed

12 files changed

+152
-4
lines changed

.DS_Store

0 Bytes
Binary file not shown.

book_cn/rust_concurrency_cookbook.pdf

325 KB
Binary file not shown.

container_primitive/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ edition = "2021"
77

88
[dependencies]
99
beef = "0.5.2"
10+
once_cell = "1.18.0"

sync_primitive/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ edition = "2021"
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9-
rand = "0.8.5"
9+
once_cell = "1.18.0"
10+
rand = "0.8.5"

sync_primitive/src/barrier.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::time;
12
use std::sync::Arc;
23
use std::sync::Barrier;
34
use std::thread;
@@ -21,6 +22,33 @@ pub fn barrier_example() {
2122
}));
2223
}
2324

25+
for handle in handles {
26+
handle.join().unwrap();
27+
}
28+
}
29+
30+
pub fn barrier_recycle_example() {
31+
let barrier = Arc::new(Barrier::new(10));
32+
let mut handles = vec![];
33+
34+
for _ in 0..10 {
35+
let barrier = barrier.clone();
36+
handles.push(thread::spawn(move || {
37+
println!("before wait1");
38+
let dur = rand::thread_rng().gen_range(100..1000);
39+
thread::sleep(std::time::Duration::from_millis(dur));
40+
41+
//step1
42+
barrier.wait();
43+
println!("after wait1");
44+
thread::sleep(time::Duration::from_secs(1));
45+
46+
//step2
47+
barrier.wait();
48+
println!("after wait2");
49+
}));
50+
}
51+
2452
for handle in handles {
2553
handle.join().unwrap();
2654
}

sync_primitive/src/exclusive.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::sync::Exclusive;
2+
3+
pub fn exclusive_lock_example() {
4+
let mut exclusive = Exclusive::new(92);
5+
println!("ready");
6+
std::thread::spawn(move || {
7+
let counter = exclusive.get_mut();
8+
println!("{}", *counter);
9+
*counter = 100;
10+
}).join().unwrap();
11+
12+
}

sync_primitive/src/lazy.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use std::cell::LazyCell;
2+
use std::sync::LazyLock;
3+
4+
pub fn lazy_cell_example() {
5+
let lazy: LazyCell<i32> = LazyCell::new(|| {
6+
println!("initializing");
7+
92
8+
});
9+
println!("ready");
10+
println!("{}", *lazy);
11+
println!("{}", *lazy);
12+
}
13+
14+
use std::collections::HashMap;
15+
static HASHMAP: LazyLock<HashMap<i32, String>> = LazyLock::new(|| {
16+
println!("initializing");
17+
let mut m = HashMap::new();
18+
m.insert(13, "Spica".to_string());
19+
m.insert(74, "Hoyten".to_string());
20+
m
21+
});
22+
23+
pub fn lazy_lock_example() {
24+
println!("ready");
25+
std::thread::spawn(|| {
26+
println!("{:?}", HASHMAP.get(&13));
27+
}).join().unwrap();
28+
println!("{:?}", HASHMAP.get(&74));
29+
}

sync_primitive/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#![feature(sync_unsafe_cell)]
2+
#![feature(lazy_cell)]
3+
#![feature(exclusive_wrapper)]
24

35
pub mod arc;
46
pub mod mutex;
@@ -8,6 +10,8 @@ pub mod barrier;
810
pub mod cond;
911
pub mod mpsc;
1012
pub mod atomic;
13+
pub mod lazy;
14+
pub mod exclusive;
1115

1216
pub use arc::*;
1317
pub use mutex::*;
@@ -16,4 +20,6 @@ pub use once::*;
1620
pub use barrier::*;
1721
pub use cond::*;
1822
pub use mpsc::*;
19-
pub use atomic::*;
23+
pub use atomic::*;
24+
pub use lazy::*;
25+
pub use exclusive::*;

sync_primitive/src/main.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@ fn main() {
88
mutex_example1();
99
mutex_example2_poison();
1010
mutex_example3_drop();
11-
11+
1212
rwlock_example();
13+
read_after_write();
1314

1415
once_example();
1516
oncecell_example();
1617
oncelock_example();
18+
once_cell_example();
1719

1820
barrier_example();
21+
barrier_recycle_example();
1922

2023
condvar_example();
2124
condvar_example2();
@@ -25,4 +28,9 @@ fn main() {
2528

2629
atomic_example();
2730
atomic_example2();
31+
32+
lazy_cell_example();
33+
lazy_lock_example();
34+
35+
exclusive_lock_example();
2836
}

sync_primitive/src/mutex.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,4 @@ pub fn mutex_example3_drop() {
8484

8585
println!("Result: {:?}", res_mutex.lock().unwrap());
8686
}
87+

sync_primitive/src/once.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,17 @@ pub fn oncelock_example() {
5353
assert_eq!(value.unwrap().as_str(), "Hello, World!");
5454

5555
println!("OnceLock: {}", value.is_some())
56+
}
57+
58+
use std::{sync::Mutex, collections::HashMap};
59+
use once_cell::sync::Lazy;
60+
static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
61+
let mut m = HashMap::new();
62+
m.insert(13, "Spica".to_string());
63+
m.insert(74, "Hoyten".to_string());
64+
Mutex::new(m)
65+
});
66+
67+
pub fn once_cell_example() {
68+
println!("{:?}", GLOBAL_DATA.lock().unwrap());
5669
}

sync_primitive/src/rwlock.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,53 @@ pub fn rwlock_example() {
3535
}
3636

3737
println!("RwLock: {}", *rwlock.read().unwrap());
38-
}
38+
}
39+
pub fn read_after_write() {
40+
// 创建一个可共享的可变整数,使用RwLock包装
41+
let counter = Arc::new(RwLock::new(0));
42+
43+
// 创建一个线程持有读锁
44+
let read_handle = {
45+
let counter = counter.clone();
46+
thread::spawn(move || {
47+
// 获取读锁
48+
let num = counter.read().unwrap();
49+
println!("Reader#1: {}", *num);
50+
51+
// 休眠模拟读取操作
52+
thread::sleep(std::time::Duration::from_secs(10));
53+
})
54+
};
55+
56+
// 创建一个线程请求写锁
57+
let write_handle = {
58+
let counter = counter.clone();
59+
thread::spawn(move || {
60+
// 休眠一小段时间,确保读锁已经被获取
61+
thread::sleep(std::time::Duration::from_secs(1));
62+
63+
// 尝试获取写锁
64+
let mut num = counter.write().unwrap();
65+
*num += 1;
66+
println!("Writer : Incremented counter to {}", *num);
67+
})
68+
};
69+
70+
// 创建一个线程请求读锁
71+
let read_handle_2 = {
72+
let counter = counter.clone();
73+
thread::spawn(move || {
74+
// 休眠一小段时间,确保写锁已经被获取
75+
thread::sleep(std::time::Duration::from_secs(2));
76+
77+
// 尝试获取读锁
78+
let num = counter.read().unwrap();
79+
println!("Reader#2: {}", *num);
80+
})
81+
};
82+
83+
// 等待读取线程和写入线程完成
84+
read_handle.join().unwrap();
85+
write_handle.join().unwrap();
86+
read_handle_2.join().unwrap();
87+
}

0 commit comments

Comments
 (0)