rust 如何在线程之间共享可变变量?

ljo96ir5  于 2023-01-30  发布在  其他
关注(0)|答案(1)|浏览(194)

我需要有一个线程,递归检查一个变量,而主线程改变变量。然而,它似乎与move,变量是不是被改变的lambda在register。(我检查和功能的作品,它只是move使它,所以我不能改变原来的变量)
我目前创建的代码:

use std::io::stdin;
use std::thread;

use enigo::{self, Enigo, MouseControllable};
use enigo::MouseButton;

use livesplit_hotkey::*;

fn main() {
    let mut input = String::new();
    let mut started = false;

    println!("How many clicks per tick? (too many will lag)");

    stdin().read_line(&mut input).expect("Unable to read line");

    let input2 = input.trim().parse::<u16>().unwrap();

    for _ in 0 .. input2 {
        thread::spawn(move || {
            let mut enigo = Enigo::new();

            loop {
                if started {
                    println!("clicking"); // debug
                    enigo.mouse_click(MouseButton::Left);
                }
            }
        });
    }

    println!("Press f8 to toggle clicking");

    let hook = Hook::new().unwrap();

    hook.register(Hotkey { key_code: KeyCode::F8, modifiers: Modifiers::empty() },  move || {
        started = !started;
    }).expect("Unable to assign hotkey");

    loop {}
}

我知道有些东西像Arc和Mutex,但是我不确定如何正确地使用它们。

t40tm48m

t40tm48m1#

只需使用静态AtomicBool代替started

use std::io::stdin;
use std::thread;

use enigo::{self, Enigo, MouseControllable};
use enigo::MouseButton;

use livesplit_hotkey::*;

static STARTED: atomic::AtomicBool = atomic::AtomicBool::new(false);

fn main() {
    let mut input = String::new();

    println!("How many clicks per tick? (too many will lag)");

    stdin().read_line(&mut input).expect("Unable to read line");

    let input2 = input.trim().parse::<u16>().unwrap();

    for _ in 0 .. input2 {
        thread::spawn(move || {
            let mut enigo = Enigo::new();

            loop {
                if STARTED.load(atomic::Ordering::SeqCst) {
                    println!("clicking"); // debug
                    enigo.mouse_click(MouseButton::Left);
                }
            }
        });
    }

    println!("Press f8 to toggle clicking");

    let hook = Hook::new().unwrap();

    hook.register(Hotkey { key_code: KeyCode::F8, modifiers: Modifiers::empty() },  move || {
        // use xor(true) to emulate "NOT" operation
        // true ^ true -> false
        // false ^ true -> true
        STARTED.fetch_xor(true, atomic::Ordering::SeqCst);
    }).expect("Unable to assign hotkey");

    loop {}
}

注意:Ordering::SeqCst可能不是理想的原子排序,您可以使用一种不太严格的排序,但我将把它留给您。

相关问题