Skip to content
On this page

智能指针3: exercises/smart_pointers/arc1.rs

题目

rust
// arc1.rs
//
// In this exercise, we are given a Vec of u32 called "numbers" with values
// ranging from 0 to 99 -- [ 0, 1, 2, ..., 98, 99 ] We would like to use this
// set of numbers within 8 different threads simultaneously. Each thread is
// going to get the sum of every eighth value, with an offset.
//
// The first thread (offset 0), will sum 0, 8, 16, ...
// The second thread (offset 1), will sum 1, 9, 17, ...
// The third thread (offset 2), will sum 2, 10, 18, ...
// ...
// The eighth thread (offset 7), will sum 7, 15, 23, ...
//
// Because we are using threads, our values need to be thread-safe.  Therefore,
// we are using Arc.  We need to make a change in each of the two TODOs.
//
// Make this code compile by filling in a value for `shared_numbers` where the
// first TODO comment is, and create an initial binding for `child_numbers`
// where the second TODO comment is. Try not to create any copies of the
// `numbers` Vec!
//
// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint.

// I AM NOT DONE

#![forbid(unused_imports)] // Do not change this, (or the next) line.
use std::sync::Arc;
use std::thread;

fn main() {
    let numbers: Vec<_> = (0..100u32).collect();
    let shared_numbers = // TODO
    let mut joinhandles = Vec::new();

    for offset in 0..8 {
        let child_numbers = // TODO
        joinhandles.push(thread::spawn(move || {
            let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
            println!("Sum of offset {} is {}", offset, sum);
        }));
    }
    for handle in joinhandles.into_iter() {
        handle.join().unwrap();
    }
}

在本练习中,我们得到一个名为numbers的 u32 Vec,其值范围为 0 到 99 -- [ 0, 1, 2, ..., 98, 99 ] 我们希望使用这组数字同时在8个不同的线程中。 每个线程都将获得每隔八个值的总和,并带有偏移量offset。

  • 第一个线程(偏移量 0)将对 0, 8, 16, ... 求和
  • 第二个线程(偏移量 1)将对 1, 9, 17, ... 求和
  • 第三个线程(偏移量 2)将对 2, 10, 18, ... 求和
  • ...
  • 第八个线程(偏移量 7)将对 7, 15, 23, ... 求和

因为我们使用线程,所以我们的值需要是线程安全的。 因此,我们使用 Arc。 我们需要对这两个 TODO 分别进行更改。

通过在第一个 TODO 注释所在的位置填写 shared_numbers 的值来编译此代码,并在第二个 TODO 注释所在的位置为 child_numbers 创建初始绑定。 尽量不要创建numbers Vec 的任何副本!

题目解析

在这个题目中shared_numbers应该时要在各个线程之间共享的,所以要声明为Arc类型。

而在线程中的child_numbers,只不过是Arc的clone。

rust
#![forbid(unused_imports)] // Do not change this, (or the next) line.
use std::sync::Arc;
use std::thread;

fn main() {
    let numbers: Vec<_> = (0..100u32).collect();
    let shared_numbers = // TODO 
    let shared_numbers = Arc::new(numbers);  
    let mut joinhandles = Vec::new();

    for offset in 0..8 {
        let child_numbers = // TODO 
        let child_numbers = shared_numbers.clone();  
        joinhandles.push(thread::spawn(move || {
            let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
            println!("Sum of offset {} is {}", offset, sum);
        }));
    }
    for handle in joinhandles.into_iter() {
        handle.join().unwrap();
    }
}

参考资料

Powered by VitePress