Skip to content

Commit b07bece

Browse files
committed
add the chapter 4
1 parent d7a43ae commit b07bece

File tree

14 files changed

+257
-111
lines changed

14 files changed

+257
-111
lines changed

.DS_Store

0 Bytes
Binary file not shown.

asyncwait/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ bytes = "1.2.1"
1414
futures = { version = "0.3.24", features = ["executor", "thread-pool"] }
1515
futures-lite = "1.12.0"
1616
futures-util = "0.3.24"
17+
monoio = "0.1.9"
1718
smol = "1.2.5"
1819
tokio = { version = "1.21.2", features = ["full"] }
20+
value-bag = "1.4.1"

asyncwait/src/lib.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
#![feature(type_alias_impl_trait)]
2+
#![feature(impl_trait_in_assoc_type)]
3+
4+
25
// #![feature(return_position_impl_trait_in_trait)]
36

4-
pub mod asyncio;
5-
pub mod future;
6-
pub mod runtimes;
7-
pub mod gat;
8-
pub mod async_trait_example;
7+
mod asyncio;
8+
mod future;
9+
mod runtimes;
10+
mod gat;
11+
mod async_trait_example;
12+
mod monoio_example;
913

1014
pub use asyncio::*;
1115
pub use future::*;
1216
pub use runtimes::*;
1317
pub use gat::*;
1418
pub use async_trait_example::*;
19+
pub use monoio_example::*;
20+
1521

asyncwait/src/main.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,25 @@ fn main() {
55
futures_async();
66
futures_lite_async();
77
async_std();
8+
async_std_task();
89
smol_async();
910

1011
timefuture_async();
1112

13+
try_join();
1214
join();
1315
select();
1416
futures_select();
17+
smol_zip();
1518

1619
stream();
1720

1821
kviterator_example();
1922

2023
async_trait_example();
24+
25+
match monoio_example() {
26+
Ok(_) => println!("monoio_example: Ok"),
27+
Err(e) => println!("monoio_example: Err: {}", e),
28+
}
2129
}

asyncwait/src/monoio_example.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
use monoio::fs::File;
3+
4+
5+
pub fn monoio_example() -> Result<(), Box<dyn std::error::Error>>{
6+
monoio::start::<monoio::LegacyDriver, _>(async {
7+
println!("monoio_example: Hello world!");
8+
9+
// Open a file
10+
let file = File::open("LICENSE").await?;
11+
12+
let buf = vec![0; 4096];
13+
// Read some data, the buffer is passed by ownership and
14+
// submitted to the kernel. When the operation completes,
15+
// we get the buffer back.
16+
let (res, buf) = file.read_at(buf, 0).await;
17+
let n = res?;
18+
19+
// Display the contents
20+
println!("monoio_example: {:?}", &buf[..n]);
21+
22+
Ok(())
23+
})
24+
}
25+

asyncwait/src/runtimes.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ use futures::try_join;
44
use futures::StreamExt;
55
use futures::{
66
future::FutureExt, // for `.fuse()`
7+
join,
78
pin_mut,
89
select,
910
};
1011

12+
use async_std::task;
13+
1114
pub fn tokio_async() {
1215
let rt = tokio::runtime::Runtime::new().unwrap();
1316
rt.block_on(async {
@@ -54,11 +57,22 @@ pub fn async_std() {
5457
async_std::task::block_on(async { println!("Hello from async_std") })
5558
}
5659

60+
pub fn async_std_task() {
61+
task::block_on(async {
62+
task::spawn(get_book());
63+
task::spawn(get_music());
64+
65+
println!("in async_std_task");
66+
});
67+
}
68+
5769
pub fn smol_async() {
58-
smol::block_on(async { println!("Hello from smol") })
70+
smol::block_on(async { println!("Hello from smol") });
5971
}
6072

73+
#[derive(Debug)]
6174
struct Book();
75+
#[derive(Debug)]
6276
struct Music();
6377

6478
async fn get_book() -> Result<Book, String> {
@@ -69,14 +83,24 @@ async fn get_music() -> Result<Music, String> {
6983
println!("in get_music");
7084
Ok(Music())
7185
}
72-
async fn get_book_and_music() -> Result<(Book, Music), String> {
73-
let book_fut = get_book();
74-
let music_fut = get_music();
75-
try_join!(book_fut, music_fut)
86+
87+
pub fn try_join() {
88+
futures_lite::future::block_on(async {
89+
let book_fut = get_book();
90+
let music_fut = get_music();
91+
println!("try_join: {:?}", try_join!(book_fut, music_fut));
92+
});
7693
}
7794

7895
pub fn join() {
79-
futures_lite::future::block_on(async { get_book_and_music().await }).unwrap();
96+
let a = async { 1 };
97+
let b = async { 2 };
98+
let c = async { 3 };
99+
100+
futures_lite::future::block_on(async {
101+
println!("join: {:?}", join!(get_book(), get_music()));
102+
println!("join: {:?}", join!(a, b, c));
103+
});
80104
}
81105

82106
pub fn select() {
@@ -112,3 +136,21 @@ pub fn futures_select() {
112136
assert_eq!(total, 10);
113137
});
114138
}
139+
140+
pub fn smol_zip() {
141+
smol::block_on(async {
142+
use smol::future::{try_zip, zip, FutureExt};
143+
144+
let future1 = async { 1 };
145+
let future2 = async { 2 };
146+
147+
let result = zip(future1, future2);
148+
println!("smol_zip: {:?}", result.await);
149+
150+
let future1 = async { Ok::<i32, i32>(1) };
151+
let future2 = async { Err::<i32, i32>(2) };
152+
153+
let result = try_zip(future1, future2).await;
154+
println!("smol_try_zip: {:?}", result);
155+
});
156+
}

book_cn/rust_concurrency_cookbook.pdf

123 KB
Binary file not shown.

container_primitive/Cargo.toml

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

88
[dependencies]
9+
beef = "0.5.2"

container_primitive/src/box.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::boxed::ThinBox;
12
// Box<T>, casually referred to as a ‘box’, provides the simplest form of heap allocation in Rust.
23
// Boxes provide ownership for this allocation, and drop their contents when they go out of scope.
34
// Boxes also ensure that they never allocate more than isize::MAX bytes.
@@ -17,3 +18,18 @@ pub fn box_example2() {
1718
println!("{list:?}");
1819
}
1920

21+
pub fn thin_box_example() {
22+
use std::mem::{size_of, size_of_val};
23+
let size_of_ptr = size_of::<*const ()>();
24+
25+
let box_five = Box::new(5);
26+
let box_slice = Box::<[i32]>::new_zeroed_slice(5);
27+
assert_eq!(size_of_ptr, size_of_val(&box_five));
28+
assert_eq!(size_of_ptr * 2, size_of_val(&box_slice));
29+
30+
31+
let five = ThinBox::new(5);
32+
let thin_slice = ThinBox::<[i32]>::new_unsize([1, 2, 3, 4]);
33+
assert_eq!(size_of_ptr, size_of_val(&five));
34+
assert_eq!(size_of_ptr, size_of_val(&thin_slice));
35+
}

container_primitive/src/cell.rs

Lines changed: 18 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use std::cell::*;
44
use std::collections::HashMap;
5-
use std::rc::Rc;
5+
use std::sync::LazyLock;
66

77
// Shareable mutable containers.
88
// Shareable mutable containers exist to permit mutability in a controlled manner, even in the presence of aliasing.
@@ -27,6 +27,8 @@ pub fn cell_example() {
2727
let _ = my_struct.regular_field;
2828
// my_struct.regular_field = 100;
2929
my_struct.special_field.set(100);
30+
31+
my_struct.special_field.update(|v| v + 1);
3032
}
3133

3234
pub fn refcell_example() {
@@ -53,23 +55,7 @@ pub fn refcell_example() {
5355
println!("special_field = {}", my_struct.special_field.borrow());
5456
}
5557

56-
pub fn rc_refcell_example() {
57-
let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
58-
// Create a new block to limit the scope of the dynamic borrow
59-
{
60-
let mut map: RefMut<_> = shared_map.borrow_mut();
61-
map.insert("africa", 92388);
62-
map.insert("kyoto", 11837);
63-
map.insert("piccadilly", 11826);
64-
map.insert("marbles", 38);
65-
}
6658

67-
// Note that if we had not let the previous borrow of the cache fall out
68-
// of scope then the subsequent borrow would cause a dynamic thread panic.
69-
// This is the major hazard of using `RefCell`.
70-
let total: i32 = shared_map.borrow().values().sum();
71-
println!("{total}");
72-
}
7359

7460
pub fn once_cell_example() {
7561
let cell = OnceCell::new();
@@ -90,78 +76,18 @@ pub fn lazy_cell_example() {
9076
println!("{}", *lazy);
9177
}
9278

93-
pub fn myrc_example() {
94-
let s = example::Rc::new("hello world");
95-
let s1 = s.clone();
96-
97-
let v = s1.value();
98-
println!("myrc value: {}", v);
99-
}
100-
101-
pub mod example {
102-
use std::cell::Cell;
103-
use std::marker::PhantomData;
104-
use std::process::abort;
105-
use std::ptr::NonNull;
106-
107-
pub struct Rc<T: ?Sized> {
108-
ptr: NonNull<RcBox<T>>,
109-
phantom: PhantomData<RcBox<T>>,
110-
}
111-
112-
impl<T> Rc<T> {
113-
pub fn new(t: T) -> Self {
114-
let ptr = Box::new(RcBox {
115-
strong: Cell::new(1),
116-
refcount: Cell::new(1),
117-
value: t,
118-
});
119-
let ptr = NonNull::new(Box::into_raw(ptr)).unwrap();
120-
Self {
121-
ptr: ptr,
122-
phantom: PhantomData,
123-
}
124-
}
125-
126-
pub fn value(&self) -> &T {
127-
&self.inner().value
128-
}
129-
}
130-
131-
132-
struct RcBox<T: ?Sized> {
133-
strong: Cell<usize>,
134-
refcount: Cell<usize>,
135-
value: T,
136-
}
137-
138-
impl<T: ?Sized> Clone for Rc<T> {
139-
fn clone(&self) -> Rc<T> {
140-
self.inc_strong();
141-
Rc {
142-
ptr: self.ptr,
143-
phantom: PhantomData,
144-
}
145-
}
146-
}
147-
148-
trait RcBoxPtr<T: ?Sized> {
149-
fn inner(&self) -> &RcBox<T>;
150-
151-
fn strong(&self) -> usize {
152-
self.inner().strong.get()
153-
}
154-
155-
fn inc_strong(&self) {
156-
self.inner()
157-
.strong
158-
.set(self.strong().checked_add(1).unwrap_or_else(|| abort()));
159-
}
160-
}
161-
162-
impl<T: ?Sized> RcBoxPtr<T> for Rc<T> {
163-
fn inner(&self) -> &RcBox<T> {
164-
unsafe { self.ptr.as_ref() }
165-
}
166-
}
167-
}
79+
static HASHMAP: LazyLock<HashMap<i32, String>> = LazyLock::new(|| {
80+
println!("initializing");
81+
let mut m = HashMap::new();
82+
m.insert(13, "Spica".to_string());
83+
m.insert(74, "Hoyten".to_string());
84+
m
85+
});
86+
87+
pub fn lazy_lock() {
88+
println!("ready");
89+
std::thread::spawn(|| {
90+
println!("{:?}", HASHMAP.get(&13));
91+
}).join().unwrap();
92+
println!("{:?}", HASHMAP.get(&74));
93+
}

container_primitive/src/cow.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
use std::borrow::Cow;
2+
use std::mem::size_of;
23

3-
// The type Cow is a smart pointer providing clone-on-write functionality:
4-
// it can enclose and provide immutable access to borrowed data,
5-
// and clone the data lazily when mutation or ownership is required.
4+
// The type Cow is a smart pointer providing clone-on-write functionality:
5+
// it can enclose and provide immutable access to borrowed data,
6+
// and clone the data lazily when mutation or ownership is required.
67
pub fn cow_example() {
78
let origin = "hello world";
8-
let mut cow = Cow::from(origin);
9+
let mut cow = Cow::from(origin); // Cow::Borrowed
910
assert_eq!(cow, "hello world");
1011

1112
// Cow can be borrowed as a str
1213
let s: &str = &cow;
1314
assert_eq!(s, "hello world");
1415

16+
assert_eq!(s.len(), cow.len());
17+
1518
// Cow can be borrowed as a mut str
1619
let s: &mut str = cow.to_mut();
1720
s.make_ascii_uppercase();
@@ -54,4 +57,19 @@ pub fn cow_example2() {
5457
// No clone occurs because `input` is already owned.
5558
let mut input = Cow::from(vec![-1, 0, 1]);
5659
abs_all(&mut input);
57-
}
60+
61+
}
62+
63+
pub fn beef_cow() {
64+
let borrowed: beef::Cow<str> = beef::Cow::borrowed("Hello");
65+
let owned: beef::Cow<str> = beef::Cow::owned(String::from("World"));
66+
let _ = beef::Cow::from("Hello");
67+
68+
assert_eq!(format!("{} {}!", borrowed, owned), "Hello World!",);
69+
70+
const WORD: usize = size_of::<usize>();
71+
72+
assert_eq!(size_of::<std::borrow::Cow<str>>(), 3 * WORD);
73+
assert_eq!(size_of::<beef::Cow<str>>(), 3 * WORD);
74+
assert_eq!(size_of::<beef::lean::Cow<str>>(), 2 * WORD);
75+
}

container_primitive/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
#![feature(once_cell)]
1+
#![feature(lazy_cell)]
2+
#![feature(thin_box)]
3+
#![feature(new_uninit)]
4+
#![feature(cell_update)]
25

36
pub mod cow;
47
pub mod r#box;

0 commit comments

Comments
 (0)