在线程之间可变地共享i32

时间:2017-03-17 04:25:48

标签: multithreading rust

我是Rust和线程的新手,我正在尝试打印一个数字,同时在另一个线程中添加它。我怎么能做到这一点?

use std::thread;
use std::time::Duration;

fn main() {
    let mut num = 5;
    thread::spawn(move || {
        loop {
            num += 1;
            thread::sleep(Duration::from_secs(10));
        }
    });
    output(num);
}

fn output(num: i32) {
    loop {
        println!("{:?}", num);
        thread::sleep(Duration::from_secs(5));
    }
}

上面的代码不起作用:它总是只打印5,就像数字永远不会增加一样。

2 个答案:

答案 0 :(得分:8)

请阅读"Concurrency" chapter, "Safe Shared Mutable State" section of The Rust Book,它会详细说明如何执行此操作。

简而言之:

  1. 您的程序无效,因为datasource 已复制,因此num并且该主题在该号码的不同副本上运行。如果output()不可复制,Rust编译器将无法编译并出现错误。
  2. 由于您需要在多个线程之间共享相同的变量,因此需要将其包装在Arc a tomic r eference- 中c 安装变量)
  3. 由于您需要修改num内的变量,因此需要将其放在MutexRwLock中。您使用Arc方法从.lock()中获取可变引用。该方法将确保在该可变引用的生命周期内对整个过程进行独占访问。
  4. Mutex

    您可能还想阅读:

答案 1 :(得分:2)

另一个答案可以解决任何类型的问题,但是作为pnkfelix observes,原子包装器类型是另一种适用于i32特定情况的解决方案。

从Rust 1.0开始,您可以使用AtomicBoolAtomicPtr<T>AtomicIsizeAtomicUsize来同步对bool,{{1}的多线程访问},*mut Tisize值。在Rust 1.34中,几个新的usize类型已经稳定,包括Atomic。 (请查看AtomicI32文档以获取当前列表。)

使用原子类型最有可能比锁定std::sync::atomicMutex更有效率,但是需要更多地注意内存排序的底层细节。如果您的线程共享的数据超出了标准原子类型之一的容纳量,则您可能希望使用RwLock而不是多个Mutex

也就是说,这是kennytm使用Atomic而不是AtomicI32的答案的版本:

Mutex<i32>
共享所有权仍然需要

use std::sync::{ atomic::{AtomicI32, Ordering}, Arc, }; use std::thread; use std::time::Duration; fn main() { let num = Arc::new(AtomicI32::new(5)); let num_clone = num.clone(); thread::spawn(move || loop { num.fetch_add(1, Ordering::SeqCst); thread::sleep(Duration::from_secs(10)); }); output(num_clone); } fn output(num: Arc<AtomicI32>) { loop { println!("{:?}", num.load(Ordering::SeqCst)); thread::sleep(Duration::from_secs(5)); } } (但请参见How can I pass a reference to a stack variable to a thread?)。

选择正确的存储器Arc并非易事。 Ordering是最保守的选择,但是如果仅共享一个内存地址,则SeqCst也应该起作用。有关更多信息,请参见下面的链接。

链接

  1. std::sync::atomic module documentation
  2. Atomics The Rustonomicon 的章节)
  3. LLVM Memory Model for Concurrent OperationsAtomic Instructions and Concurrency Guide