【问题标题】:Rust thread runs more than anotherRust 线​​程比另一个线程运行得更多
【发布时间】:2022-11-25 22:34:23
【问题描述】:

大家下午好,我正在学习rust,我想问一个问题,在下面的代码中,一个线程总是比另一个线程工作得更多,线程之间似乎没有正常的工作分配。

我用 C++ 编写了相同的代码,它也能正常工作,有人可以帮助我并告诉我 Rust 哪里出错了吗?

代码:

use std::fmt;
use std::sync::{Arc, Mutex};
use std::thread;
use tokio::time::Duration;
struct Client {
    id: i32,
}
impl fmt::Display for Client {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        writeln!(f, "Client id: {:?}", self.id)
    }
}
fn main() {
    // ======================
    let client: Client = Client { id: 0 };
    let counter = Arc::new(Mutex::new(client));
    let mut handles = vec![];

    // ======================
    // THREAD 1
    // ======================
    let safe_client_1 = Arc::clone(&counter);
    let thread_1 = thread::spawn(move || loop {
        let mut num = safe_client_1.lock().unwrap();
        num.id += 1;
        print!("thread 1: {}", num);
        thread::sleep(Duration::from_secs(1));
    });
    handles.push(thread_1);

    // ======================
    // THREAD 2
    // ======================
    let safe_client_2 = Arc::clone(&counter);
    let thread_2 = thread::spawn(move || loop {
        let mut num = safe_client_2.lock().unwrap();
        num.id -= 1;
        print!("thread 2: {}", num);
        thread::sleep(Duration::from_secs(1));
    });

    loop {}
}

输出:

thread 1: Client id: 1
thread 1: Client id: 2
thread 2: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 2: Client id: -2
thread 2: Client id: -3
thread 2: Client id: -4
thread 2: Client id: -5
thread 2: Client id: -6
thread 2: Client id: -7
thread 1: Client id: -6
thread 2: Client id: -7
thread 2: Client id: -8
thread 2: Client id: -9
thread 2: Client id: -10
thread 2: Client id: -11
thread 2: Client id: -12
thread 2: Client id: -13
thread 2: Client id: -14
thread 2: Client id: -15
thread 2: Client id: -16
thread 2: Client id: -17
thread 2: Client id: -18
thread 2: Client id: -19
thread 2: Client id: -20
thread 2: Client id: -21
thread 2: Client id: -22
thread 2: Client id: -23
thread 2: Client id: -24
thread 2: Client id: -25
thread 2: Client id: -26
thread 2: Client id: -27

解决方案代码:

use std::fmt;
use std::sync::{Arc, Mutex};
use std::thread;
use tokio::time::Duration;
struct Client {
    id: i32,
}
impl fmt::Display for Client {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        writeln!(f, "Client id: {:?}", self.id)
    }
}
fn main() {
    // ======================
    let client: Client = Client { id: 0 };
    let counter = Arc::new(Mutex::new(client));

    // ======================
    // THREAD 1
    // ======================
    let safe_client_1 = Arc::clone(&counter);
    let thread_1 = thread::spawn(move || loop {
        let mut num = safe_client_1.lock().unwrap();
        num.id += 1;
        print!("thread 1: {}", num);
        drop(num);
        thread::sleep(Duration::from_secs(1));
    });

    // ======================
    // THREAD 2
    // ======================
    let safe_client_2 = Arc::clone(&counter);
    let thread_2 = thread::spawn(move || loop {
        let mut num = safe_client_2.lock().unwrap();
        num.id -= 1;
        print!("thread 2: {}", num);
        drop(num);

        thread::sleep(Duration::from_secs(1));
    });

    loop {}
}

输出:

thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0
thread 1: Client id: 1
thread 2: Client id: 0
thread 2: Client id: -1
thread 1: Client id: 0

【问题讨论】:

    标签: rust


    【解决方案1】:

    你拿着锁睡觉。改为这样做:

    let thread_1 = thread::spawn(move || loop {
        let mut num = safe_client_1.lock().unwrap();
        num.id += 1;
        print!("thread 1: {}", num);
        drop(num);
        thread::sleep(Duration::from_secs(1));
    });
    

    【讨论】:

    • 还有主线程忙循环(与工人冲突)似乎不太理想。
    • 哇这么简单 kkkkk,非常感谢你解决了问题!
    • @Masklinn 我该怎么办?能给我举个例子?
    • @ClaudioSilva join() 在子线程上等待它们完成。这似乎是您通过将其中之一添加到 handles 的向量而开始做的事情。
    • 或者只是在主线程中运行 thread_2 的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    相关资源
    最近更新 更多