【问题标题】:Why does incrementing an integer in a thread not change the value outside of the thread?为什么在线程中增加整数不会改变线程外的值?
【发布时间】:2021-01-08 18:45:01
【问题描述】:

我有这个代码:

fn main() {
    let mut total: i64 = 0;
    let pool = ThreadPool::with_name("search worker".to_owned(), num_cpus::get());
    let items = getItems(); // returns a vector of sorts
    let client = blocking::Client::new();
    for item in items {
        let t_client = client.clone(); // must clone here for some reason
        let mut took: i64 = 0;
        pool.execute(move || {
            took = worker(t_client);
            total += took;
        });
    }
    println!("{}", total);
}

fn worker(c: blocking::Client) -> i64 {
    // do some stuff and return a value
    // for sake of an example, return 25

    25
}

我必须在调用中使用move 子句才能执行。

问题在于total 变量的值仍然为零。看起来它在那个循环中被复制了,并且局部变量根本没有被修改。

我确实在took = worker(t_client);total_took += took; 上收到警告,即这些变量并非永远不会被读取。

我最终通过将该变量设为静态并使用unsafe“解决”了这个问题,但这不是解决方案。此外,最终我需要从该工作函数中获得更多结果,如果我引用一个变量,它会告诉我不能多次借用,我不太明白。

【问题讨论】:

  • 很难回答您的问题,因为它不包含minimal reproducible example。我们无法分辨代码中存在哪些 crate(及其版本)、类型、特征、字段等。如果您尝试在Rust Playground 上重现您的错误,如果可能的话,这将使我们更容易为您提供帮助,否则在全新的 Cargo 项目中,然后在edit 您的问题中包含附加信息。您可以使用Rust-specific MRE tips 来减少您在此处发布的原始代码。谢谢!
  • edit 您的问题并粘贴您所得到的准确和完整的错误——这将帮助我们了解问题所在,以便我们能够提供最好的帮助。有时试图解释错误消息很棘手,实际上错误消息的不同部分很重要。请使用直接运行编译器的消息,而不是 IDE 生成的消息,它可能会尝试为您解释错误。
  • 顺便说一句,惯用的 Rust 使用 snake_case 表示变量、方法、宏、字段和模块; UpperCamelCase 用于类型和枚举变体; SCREAMING_SNAKE_CASE 用于静态和常量。

标签: multithreading rust synchronization closures threadpool


【解决方案1】:

totali64 类型,它实现了 Copy 特征,因此它在移动时被隐式复制。如果您想在多个线程之间共享一些可变值T,您需要将其包装在Arc<Mutex<T>>Arc docsMutex docs)中,或者在这种特殊情况下,因为您使用的是i64,你可以改用AtomicI64

【讨论】:

【解决方案2】:

根据@pretzelhammer 的回答,我写了一个关于我如何让它工作的小sn-p。

let total = Arc::new(AtomicI64::new(0));
...
for ... {
  let total_c = total.clone();
  pool.execute(move || {
      total_c.fetch_add(es_helper::run_search(t_client, parsed), Ordering::Relaxed);
  });
}

【讨论】:

    猜你喜欢
    • 2021-04-09
    • 2017-06-29
    • 1970-01-01
    • 2015-06-17
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多