如何在线程之间可变地共享i32? [英] How can I mutably share an i32 between threads?

查看:93
本文介绍了如何在线程之间可变地共享i32?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Rust和threading的新手,我正在尝试打印一个数字,同时将其添加到另一个线程中.我该怎么做?

I'm new to Rust and threading and I'm trying to print out a number while adding to it in another thread. How can I accomplish this?

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,就好像数字从不增加.

The above code doesn't work: it always prints 5 as if the number is never incremented.

推荐答案

请阅读 The Rust Book的共享状态并发"一章,它详细说明了如何执行此操作.

Please read the "Shared-State Concurrency" chapter of The Rust Book, it explains how to do this in detail.

简而言之:

  1. 您的程序无法正常运行,因为num已被复制,因此output()和线程在数字的不同副本上进行操作.如果num是不可复制的,Rust编译器将无法编译,并显示错误.
  2. 由于您需要在多个线程之间共享同一变量,因此需要将其包装在 Arc ( a tomic r eference- c ounted变量)
  3. 由于您需要修改Arc中的变量,因此需要将其放入 Mutex RwLock .您可以使用.lock()方法从Mutex中获取可变引用.该方法将确保在该可变引用的生存期内对整个过程进行独占访问.
  1. Your program does not work because num is copied, so output() and the thread operate on different copies of the number. The Rust compiler will fail to compile with an error if num is not copyable.
  2. Since you need to share the same variable between multiple threads, you need to wrap it in an Arc (atomic reference-counted variable)
  3. Since you need to modify the variable inside the Arc, you need to put it in a Mutex or RwLock. You use the .lock() method to obtain a mutable reference out of a Mutex. The method will ensure exclusive access across the whole process during the lifetime of that mutable reference.

use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

fn main() {
    let num = Arc::new(Mutex::new(5));
    // allow `num` to be shared across threads (Arc) and modified
    // (Mutex) safely without a data race.

    let num_clone = num.clone();
    // create a cloned reference before moving `num` into the thread.

    thread::spawn(move || {
        loop {
            *num.lock().unwrap() += 1;
            // modify the number.
            thread::sleep(Duration::from_secs(10));
        }
    });

    output(num_clone);
}

fn output(num: Arc<Mutex<i32>>) {
    loop {
        println!("{:?}", *num.lock().unwrap());
        // read the number.
        //  - lock(): obtains a mutable reference; may fail,
        //    thus return a Result
        //  - unwrap(): ignore the error and get the real
        //    reference / cause panic on error.
        thread::sleep(Duration::from_secs(5));
    }
}

您可能还想阅读:

  • Why does Rust have mutexes and other sychronization primitives, if sharing of mutable state between tasks is not allowed?
  • What happens when an Arc is cloned?
  • How do I share a mutable object between threads using Arc? (for why we need Arc<Mutex<i32>> instead of Arc<i32>)
  • When would you use a Mutex without an Arc? (for why we need Arc<Mutex<i32>> instead of Mutex<i32>)

这篇关于如何在线程之间可变地共享i32?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆