rust - 如何在Rust中使用Mutex创建关键部分?

标签 rust synchronization thread-safety mutex

我是Rust的新手。我应该使用MutexArcprint_lots函数内创建一个关键部分,以阻止比赛条件的发生。有任何想法吗?

fn main() {
    let num_of_threads = 4;
    let mut array_of_threads = vec![];
    
    for id in 0..num_of_threads {
        array_of_threads.push(std::thread::spawn(move || print_lots(id)));
    }

    for t in array_of_threads {
        t.join().expect("Thread join failure");
    }
}

fn print_lots(id: u32) {
    println!("Begin [{}]", id);
    for _i in 0..100 {
        print!("{} ", id);
    }
    println!("\nEnd [{}]", id);
}

最佳答案

Rust中的Mutex可能与锁在您可能习惯的其他语言中的工作方式不同。 Rust Mutex并非拥有独立于值的锁,而是拥有数据并防止在未先获得锁的情况下访问数据,而该锁是在编译时强制执行的。
您得到的警告是因为您已锁定Mutex,但随后对该值没有执行任何操作。出现警告是因为几乎可以肯定这是一个错误。

fn main() {
    let foo = Mutex::new(0);
    // It's often best to just unwrap and panic if the lock is poisoned
    if let Ok(mut lock) = foo.lock() {
        *lock = 2;
        // The mutex is unlocked automatically when lock goes out of scope here
    }
    println!("{:?}", foo); // Mutex { data: 2 }
}
我猜您真正的问题是您想同步打印语句,以使不同线程的输出不会混杂在一起。
一种方法是获取StdOut上的锁,该锁实际上在内部使用锁,并提供与Mutex类似的API:
fn print_lots(id: u32) {
    let stdout = io::stdout();
    println!("Begin [{}]", id);
    let mut handle = stdout.lock();
    for _i in 0..100 {
        write!(&mut handle, "{} ", id).unwrap();
    }
    println!("\nEnd [{}]", id);
    // handle is dropped here, unlocking stdout 
}
在您的简化示例中,在每个线程中创建一个长生命周期的锁会适得其反,因为每个线程都会阻塞其他线程,并且结果是顺序的,而不是并发的。但是,如果您的真实世界代码还在继续运行,这可能仍然有意义。

关于rust - 如何在Rust中使用Mutex创建关键部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66574367/

相关文章:

rust - 如何绑定(bind) Iterator::Item 的类型?

rust - 如何添加一个字段,该字段是其他字段的加密哈希?

silverlight - 保持模型和ViewModel同步的最佳实践

java - 仅调度线程一次。

c++ - 哪些是从线程通过 PostMessage 发送 CString 的安全方法

udp - 使用 mio 使用 UDP 并收到错误 "MutBuf is not implemented for the type MutSliceBuf"

scope - 为什么泛型生命周期不符合嵌套范围的较小生命周期?

Java:如何解决读写器问题?

java - 同步方法以防止 ConcurrentModificationException

java - 这个 ENUM 方法线程安全吗?