Skip to content

Commit 6422297

Browse files
committed
add chapter-1 in Chinese
1 parent a459fb9 commit 6422297

File tree

5 files changed

+209
-4
lines changed

5 files changed

+209
-4
lines changed

book_cn/ch01 Thread.pdf

609 KB
Binary file not shown.

thread/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ rayon = "1.5.3"
1515
go-spawn = "0.1.2"
1616
num_threads = "0.1.6"
1717
parking = "2.0.0"
18+
num_cpus = "1.13.1"
1819

1920
[target.'cfg(any(windows, linux))'.dependencies]
20-
affinity = "0.1.2"
21+
affinity = "0.1.2"

thread/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,26 @@ pub fn panic_example() {
1818

1919
println!("Exiting main!")
2020
}
21+
22+
23+
pub fn panic_caught_example() {
24+
println!("Hello, panic_caught_example !");
25+
26+
let h = std::thread::spawn(|| {
27+
std::thread::sleep(std::time::Duration::from_millis(1000));
28+
let result = std::panic::catch_unwind(|| {
29+
panic!("boom");
30+
});
31+
32+
println!("panic caught, result = {}", result.is_err());
33+
});
34+
35+
let r = h.join();
36+
match r {
37+
Ok(r) => println!("All is well! {:?}", r),
38+
Err(e) => println!("Got an error! {:?}", e),
39+
}
40+
41+
println!("Exiting main!")
42+
}
43+

thread/src/main.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,24 @@ use thread::*;
22

33
fn main() {
44
start_one_thread();
5+
start_one_thread_result();
56
start_two_threads();
7+
start_n_threads();
8+
9+
current_thread();
10+
611
start_thread_with_sleep();
12+
start_thread_with_yield_now();
13+
714
start_thread_with_priority();
815
thread_builder();
916

1017
start_one_thread_with_move();
11-
start_one_thread_with_threadlocal();
18+
19+
start_threads_with_threadlocal();
1220

1321
thread_park();
22+
thread_park2();
1423
thread_park_timeout();
1524

1625
start_scoped_threads();
@@ -31,4 +40,7 @@ fn main() {
3140
park_thread();
3241

3342
panic_example();
43+
panic_caught_example();
44+
45+
info();
3446
}

thread/src/threads.rs

Lines changed: 171 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use thread_amount::thread_amount;
1616
use thread_control::*;
1717
use thread_priority::*;
1818

19+
#[cfg(not(target_os = "macos"))]
20+
use affinity::*;
21+
1922
pub fn start_one_thread() {
2023
let count = thread::available_parallelism().unwrap().get();
2124

@@ -28,6 +31,18 @@ pub fn start_one_thread() {
2831
handle.join().unwrap();
2932
}
3033

34+
pub fn start_one_thread_result() {
35+
let handle = thread::spawn(|| {
36+
println!("Hello from a thread!");
37+
200
38+
});
39+
40+
match handle.join() {
41+
Ok(v) => println!("thread result: {}", v),
42+
Err(e) => println!("error: {:?}", e),
43+
}
44+
}
45+
3146
pub fn start_two_threads() {
3247
let handle1 = thread::spawn(|| {
3348
println!("Hello from a thread1!");
@@ -41,6 +56,50 @@ pub fn start_two_threads() {
4156
handle2.join().unwrap();
4257
}
4358

59+
pub fn start_n_threads() {
60+
const N: isize = 10;
61+
62+
let handles: Vec<_> = (0..N)
63+
.map(|i| {
64+
thread::spawn(move || {
65+
println!("Hello from a thread{}!", i);
66+
})
67+
})
68+
.collect();
69+
70+
// handles.into_iter().for_each(|h| h.join().unwrap());
71+
72+
for handle in handles {
73+
handle.join().unwrap();
74+
}
75+
}
76+
77+
pub fn current_thread() {
78+
let current_thread = thread::current();
79+
println!(
80+
"current thread: {:?},{:?}",
81+
current_thread.id(),
82+
current_thread.name()
83+
);
84+
85+
let builder = thread::Builder::new()
86+
.name("foo".into()) // set thread name
87+
.stack_size(32 * 1024); // set stack size
88+
89+
let handler = builder
90+
.spawn(|| {
91+
let current_thread = thread::current();
92+
println!(
93+
"child thread: {:?},{:?}",
94+
current_thread.id(),
95+
current_thread.name()
96+
);
97+
})
98+
.unwrap();
99+
100+
handler.join().unwrap();
101+
}
102+
44103
pub fn start_thread_with_sleep() {
45104
let handle1 = thread::spawn(|| {
46105
thread::sleep(Duration::from_millis(2000));
@@ -56,6 +115,21 @@ pub fn start_thread_with_sleep() {
56115
handle2.join().unwrap();
57116
}
58117

118+
pub fn start_thread_with_yield_now() {
119+
let handle1 = thread::spawn(|| {
120+
thread::yield_now();
121+
println!("yield_now!");
122+
});
123+
124+
let handle2 = thread::spawn(|| {
125+
thread::yield_now();
126+
println!("yield_now in another thread!");
127+
});
128+
129+
handle1.join().unwrap();
130+
handle2.join().unwrap();
131+
}
132+
59133
pub fn start_thread_with_priority() {
60134
let handle1 = thread::spawn(|| {
61135
assert!(set_current_thread_priority(ThreadPriority::Min).is_ok());
@@ -97,13 +171,45 @@ pub fn start_one_thread_with_move() {
97171
let x = 100;
98172

99173
let handle = thread::spawn(move || {
100-
println!("Hello from a thread, x={}!", x);
174+
println!("Hello from a thread with move, x={}!", x);
101175
});
102176

103177
handle.join().unwrap();
178+
179+
let handle = thread::spawn(move|| {
180+
println!("Hello from a thread with move again, x={}!", x);
181+
});
182+
handle.join().unwrap();
183+
184+
let handle = thread::spawn(|| {
185+
println!("Hello from a thread without move");
186+
});
187+
handle.join().unwrap();
188+
104189
}
105190

106-
pub fn start_one_thread_with_threadlocal() {
191+
// pub fn start_one_thread_with_move2() {
192+
// let x = vec![1, 2, 3];
193+
194+
// let handle = thread::spawn(move || {
195+
// println!("Hello from a thread with move, x={:?}!", x);
196+
// });
197+
198+
// handle.join().unwrap();
199+
200+
// let handle = thread::spawn(move|| {
201+
// println!("Hello from a thread with move again, x={:?}!", x);
202+
// });
203+
// handle.join().unwrap();
204+
205+
// let handle = thread::spawn(|| {
206+
// println!("Hello from a thread without move");
207+
// });
208+
// handle.join().unwrap();
209+
210+
// }
211+
212+
pub fn start_threads_with_threadlocal() {
107213
thread_local!(static COUNTER: RefCell<u32> = RefCell::new(1));
108214

109215
COUNTER.with(|c| {
@@ -151,6 +257,18 @@ pub fn thread_park() {
151257
handle.join().unwrap();
152258
}
153259

260+
pub fn thread_park2() {
261+
let handle = thread::spawn(|| {
262+
thread::sleep(Duration::from_millis(1000));
263+
thread::park();
264+
println!("Hello from a park thread in case of unpark first!");
265+
});
266+
267+
handle.thread().unpark();
268+
269+
handle.join().unwrap();
270+
}
271+
154272
pub fn thread_park_timeout() {
155273
let handle = thread::spawn(|| {
156274
thread::park_timeout(Duration::from_millis(1000));
@@ -159,6 +277,25 @@ pub fn thread_park_timeout() {
159277
handle.join().unwrap();
160278
}
161279

280+
// pub fn wrong_start_threads_without_scoped() {
281+
// let mut a = vec![1, 2, 3];
282+
// let mut x = 0;
283+
284+
// thread::spawn(move || {
285+
// println!("hello from the first scoped thread");
286+
// dbg!(&a);
287+
// });
288+
// thread::spawn(move || {
289+
// println!("hello from the second scoped thread");
290+
// x += a[0] + a[2];
291+
// });
292+
// println!("hello from the main thread");
293+
294+
// // After the scope, we can modify and access our variables again:
295+
// a.push(4);
296+
// assert_eq!(x, a.len());
297+
// }
298+
162299
pub fn start_scoped_threads() {
163300
let mut a = vec![1, 2, 3];
164301
let mut x = 0;
@@ -223,6 +360,21 @@ pub fn rayon_scope() {
223360
assert_eq!(x, a.len());
224361
}
225362

363+
364+
// pub fn wrong_send() {
365+
// let counter = Rc::new(42);
366+
367+
// let (sender, receiver) = channel();
368+
369+
// let _t = thread::spawn(move || {
370+
// sender.send(counter).unwrap();
371+
// });
372+
373+
// let value = receiver.recv().unwrap();
374+
375+
// println!("received from the main thread: {}", value);
376+
// }
377+
226378
pub fn send_wrapper() {
227379
let wrapped_value = SendWrapper::new(Rc::new(42));
228380

@@ -326,3 +478,20 @@ pub fn park_thread() {
326478

327479
println!("park_unpark")
328480
}
481+
482+
pub fn info() {
483+
let count = thread::available_parallelism().unwrap().get();
484+
println!("available_parallelism: {}", count);
485+
486+
if let Some(count) = num_threads::num_threads() {
487+
println!("num_threads: {}", count);
488+
} else {
489+
println!("num_threads: not supported");
490+
}
491+
492+
let count = thread_amount::thread_amount();
493+
println!("thread_amount: {}", count.unwrap());
494+
495+
let count = num_cpus::get();
496+
println!("num_cpus: {}", count);
497+
}

0 commit comments

Comments
 (0)