首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Rayon的par_iter以线程安全的方式读取和修改变量?

如何使用Rayon的par_iter以线程安全的方式读取和修改变量?
EN

Stack Overflow用户
提问于 2021-04-06 19:39:28
回答 1查看 181关注 0票数 0

这段代码:

代码语言:javascript
复制
use rayon::prelude::*; // 1.5.0

fn main() {
    let mut items = Vec::new();
    items.push("hello");
    items.push("foo");
    items.push("bar");
    items.push("ipsum");

    let mut counter = 0;

    let results = items.par_iter().map(|item| {
        // do something time consuming with item
        counter += 1;
        print!("completed {} items\r", counter);
        0
    });
}

生成一个错误:

代码语言:javascript
复制
warning: unused variable: `item`
  --> src/main.rs:12:41
   |
12 |     let results = items.par_iter().map(|item| {
   |                                         ^^^^ help: if this is intentional, prefix it with an underscore: `_item`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `results`
  --> src/main.rs:12:9
   |
12 |     let results = items.par_iter().map(|item| {
   |         ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_results`

error[E0594]: cannot assign to `counter`, as it is a captured variable in a `Fn` closure
  --> src/main.rs:14:9
   |
14 |         counter += 1;
   |         ^^^^^^^^^^^^ cannot assign
EN

回答 1

Stack Overflow用户

发布于 2021-04-06 20:13:22

Rust通过从两个不同的线程写入相同的变量来防止这里的数据竞争。你有几个选择来解决这个问题。这真的要看具体情况了。

  1. 最简单的方法是使用Mutex counter。这使您可以安全地访问相同的变量。引入Mutex有消耗并行迭代器所有加速的风险,因为通过Mutex访问一切都是连续的。这是可以接受的,如果map的运行时很大并且锁定Mutex很短。
    1. 对于特定情况下的计数器原子类型,如AtomicI32工作得很好,但它们很难或不可能用于更复杂的types.
    2. Instead直接聚合在单个变量上,工作可以并行完成多次,然后合并在一起。这就是来自人造丝的reduce-functions所做的。每个线程将至少有一个计数器,它们将合并在一起以产生一个最终结果。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66967932

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档