You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust线程间共享可变变量?含Arc/Mutex使用疑问

解决方案:用Arc<Mutex<T>>实现线程间共享可变变量

原问题核心是多线程无法共享并修改同一个变量,move闭包会转移变量所有权,导致每个线程/闭包拿到独立副本,互相无法感知修改。Arc<Mutex<T>>是Rust中解决这类问题的标准方案:

  • Arc:原子引用计数,允许多个线程共享同一个值的所有权
  • Mutex:互斥锁,保证同一时间只有一个线程能访问内部值,避免数据竞争

以下是修改后的完整代码:

use std::io::stdin;
use std::thread;
use std::sync::{Arc, Mutex}; // 新增线程同步工具导入

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

use livesplit_hotkey::*;

fn main() {
    let mut input = String::new();
    // 用Arc<Mutex<bool>>包装共享变量,替代原有的mut bool
    let started = Arc::new(Mutex::new(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 {
        // 每个线程clone一份Arc,获取共享所有权
        let started_clone = Arc::clone(&started);
        thread::spawn(move || {
            let mut enigo = Enigo::new();
            loop {
                // 锁定Mutex获取内部值的访问权,unwrap处理锁中毒(简单场景下可用)
                let is_started = *started_clone.lock().unwrap();
                if is_started {
                    println!("clicking");
                    enigo.mouse_click(MouseButton::Left);
                }
                // 可选:加小sleep避免线程疯狂占用CPU
                // thread::sleep(std::time::Duration::from_millis(10));
            }
        });
    }

    println!("Press f8 to toggle clicking");
    let hook = Hook::new().unwrap();

    // 热键闭包同样clone Arc
    let started_hook_clone = Arc::clone(&started);
    hook.register(
        Hotkey { key_code: KeyCode::F8, modifiers: Modifiers::empty() },
        move || {
            // 锁定Mutex并修改内部值
            let mut started_ref = started_hook_clone.lock().unwrap();
            *started_ref = !*started_ref;
        }
    ).expect("Unable to assign hotkey");

    loop {}
}

关键改动说明

  1. 变量包装:用Arc<Mutex<bool>>替代原有的mut bool,让变量具备多线程共享能力
  2. 所有权共享:每个线程和热键闭包通过Arc::clone获取独立的引用计数实例,所有实例指向同一个Mutex包裹的bool值
  3. 线程安全访问:读写变量前必须调用lock()获取Mutex锁,确保同一时间只有一个线程操作变量
  4. 性能优化(可选):在点击循环中加入thread::sleep,避免线程无休占用CPU资源

内容的提问来源于stack exchange,提问作者HyperCodec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:15:55