Нить ржавчины работает больше, чем другая

Добрый день всем, изучаю 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
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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));
});

Кроме того, наличие цикла занятости основного потока (конфликтующего с рабочими потоками) кажется менее чем идеальным.

Masklinn 25.11.2022 15:20

Ничего себе, это просто kkkkk, большое спасибо, проблема решена!

Claudio Silva 25.11.2022 15:20

@Masklinn, как мне поступить? Можете ли вы привести пример?

Claudio Silva 25.11.2022 15:22

@ClaudioSilva join() в детских темах, чтобы дождаться их завершения. Кажется, это то, что вы начали делать, добавив один из них к вектору handles.

Masklinn 25.11.2022 15:24

Или просто запустите код thread_2 в основном потоке.

cafce25 25.11.2022 15:26

@Masklinn теперь я понимаю вопрос, я поставил join , но поскольку потоки не останавливаются, я в итоге удалил соединение и поставил цикл, чтобы программа не заканчивалась. Спасибо брат

Claudio Silva 25.11.2022 15:27

Другие вопросы по теме