Skip to content

Commit 802ce38

Browse files
committed
提交线程实验
1 parent 1196ac3 commit 802ce38

File tree

1 file changed

+55
-18
lines changed
  • exercises/01_concurrency_sync/01_thread_spawn/src

1 file changed

+55
-18
lines changed

exercises/01_concurrency_sync/01_thread_spawn/src/lib.rs

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use std::cell::RefCell;
3636
#[allow(unused_imports)]
3737
use std::thread;
38+
use std::thread::sleep;
3839
#[allow(unused_imports)]
3940
use std::time::Duration;
4041

@@ -154,20 +155,28 @@ use std::time::Duration;
154155
/// Hint: Use `thread::spawn` and `move` closure.
155156
#[allow(unused_variables)]
156157
pub fn double_in_thread(numbers: Vec<i32>) -> Vec<i32> {
157-
// TODO: Create a new thread to multiply each element of numbers by 2
158+
// Create a new thread to multiply each element of numbers by 2
158159
// Use thread::spawn and move closure
160+
let handle = thread::spawn(move || {
161+
numbers.iter().map( |i| i * 2).collect::<Vec<i32>>()
162+
});
159163
// Use join().unwrap() to get result
160-
todo!()
164+
handle.join().unwrap()
161165
}
162166

163167
/// Sum two vectors in parallel, returning a tuple of two sums.
164168
///
165169
/// Hint: Create two threads for each vector.
166170
#[allow(unused_variables)]
167171
pub fn parallel_sum(a: Vec<i32>, b: Vec<i32>) -> (i32, i32) {
168-
// TODO: Create two threads to sum a and b respectively
169-
// Join both threads to get results
170-
todo!()
172+
// Create two threads to sum a and b respectively
173+
let (sum_a,sum_b) = thread::scope(|s| {
174+
let handle_a = s.spawn(|| a.iter().sum());
175+
let handle_b = s.spawn(|| b.iter().sum());
176+
(handle_a.join().unwrap(), handle_b.join().unwrap())
177+
});
178+
// Join both threads to get results()
179+
(sum_a, sum_b)
171180
}
172181

173182
// ============================================================================
@@ -182,10 +191,15 @@ pub fn parallel_sum(a: Vec<i32>, b: Vec<i32>) -> (i32, i32) {
182191
/// Hint: `thread::sleep` causes the current thread to block; it does not affect other threads.
183192
#[allow(unused_variables)]
184193
pub fn named_sleeper(value: i32, ms: u64) -> i32 {
185-
// TODO: Create a thread builder with name "sleeper"
186-
// TODO: Spawn a thread that sleeps for `ms` milliseconds and returns `value`
187-
// TODO: Join the thread and return the value
188-
todo!()
194+
// Create a thread builder with name "sleeper"
195+
let builder = thread::Builder::new().name("sleeper".to_string());
196+
// Spawn a thread that sleeps for `ms` milliseconds and returns `value`
197+
let handle = builder.spawn(move || {
198+
sleep(Duration::from_millis(ms));
199+
value
200+
}).unwrap();
201+
// Join the thread and return the value
202+
handle.join().unwrap()
189203
}
190204

191205
thread_local! {
@@ -199,8 +213,17 @@ thread_local! {
199213
///
200214
/// Hint: Use `THREAD_COUNT.with(|cell| { ... })` to access the thread‑local variable.
201215
pub fn increment_thread_local() -> usize {
202-
// TODO: Use THREAD_COUNT.with to increment and return the new count
203-
todo!()
216+
// Use THREAD_COUNT.with to increment and return the new count
217+
thread_local! {
218+
pub static THREAD_COUNT: RefCell<usize> = const {
219+
RefCell::new(0)
220+
};
221+
}
222+
THREAD_COUNT.with(|thread_count|{
223+
let mut count = thread_count.borrow_mut();
224+
*count += 1;
225+
*count }
226+
)
204227
}
205228

206229
/// Spawn two threads using a **scoped thread** to compute the sum of two slices without moving ownership.
@@ -213,10 +236,14 @@ pub fn increment_thread_local() -> usize {
213236
/// making the borrow safe.
214237
#[allow(unused_variables)]
215238
pub fn scoped_slice_sum(a: &[i32], b: &[i32]) -> (i32, i32) {
216-
// TODO: Use thread::scope to spawn two threads
217-
// TODO: Each thread sums its slice
218-
// TODO: Wait for both threads and return the results
219-
todo!()
239+
// Use thread::scope to spawn two threads
240+
// Each thread sums its slice
241+
// Wait for both threads and return the results
242+
thread::scope(|s| {
243+
let handle_a = s.spawn(|| a.iter().sum());
244+
let handle_b = s.spawn(|| b.iter().sum());
245+
(handle_a.join().unwrap(), handle_b.join().unwrap())
246+
})
220247
}
221248

222249
/// Handle a possible panic in a spawned thread.
@@ -231,9 +258,19 @@ pub fn scoped_slice_sum(a: &[i32], b: &[i32]) -> (i32, i32) {
231258
/// In this exercise, the inner type is just `i32`, not a `Result`.
232259
#[allow(unused_variables)]
233260
pub fn handle_panic(value: i32, should_panic: bool) -> Result<i32, ()> {
234-
// TODO: Spawn a thread that either panics or returns value
235-
// TODO: Join and map the result appropriately
236-
todo!()
261+
// Spawn a thread that either panics or returns value
262+
let handle = thread::spawn(move||{
263+
if should_panic {
264+
panic!("print to stderr");
265+
}else {
266+
value
267+
}
268+
});
269+
// Join and map the result appropriately
270+
match handle.join() {
271+
Ok(result) => Ok(result),
272+
Err(_) => Err(()),
273+
}
237274
}
238275

239276
#[cfg(test)]

0 commit comments

Comments
 (0)