首页 > 解决方案 > 如何确保一段代码在任何给定时间总是被一个线程使用?

问题描述

我正在编写一个需要使用可变静态变量才能工作的函数(消息循环的奇怪实现)。为了在任何给定时间只允许一个编写者访问这些变量,我需要使对该函数的访问独占(访问它的第一个线程)。

使用AtomicBool

我的第一个猜测是使用AtomicBool

use std::sync::atomic::{Ordering, AtomicBool};

static FLAG: AtomicBool = AtomicBool::new(false);

fn my_exclusive_function() {
    if FLAG.load(Ordering::SeqCst) {
        panic!("Haha, too late!")
    }
    
    FLAG.store(true, Ordering::SeqCst);

    /* Do stuff */
}

这段代码有一个明显的缺陷:如果两个线程碰巧同时读取FLAG,他们都会认为这对他们来说是可以继续的。

使用Mutex<()>

然后我考虑使用aMutex<()>作为它的锁。

use std::sync::Mutex;

static FLAG: Mutex<()> = Mutex::new(());

fn my_exclusive_function() {
    let _lock = FLAG.try_lock() {
        Ok(lock) => lock,
        Err(_) => panic!("Haha, too late!"),
    };

    /* Do stuff */

    // `_lock` gets dropped here, another thread can now access the function
}

这里有两个问题:

  1. Mutex::new不是const使我无法初始化Mutex. 我可以使用像lazy_static这里这样的库,但如果我可以避免额外的依赖,那就太好了。
  2. 即使我使用lazy_static,用户定义的函数(实际上是消息循环内部的处理程序)可能会恐慌并毒害互斥锁。在这里,我可以使用类似的线程方库,parking_lot但这将是另一个额外的依赖项。

如果没有其他选择,我愿意使用这些,但如果我可以避免它,那就更好了。

这样做的正确方法是什么?这只是一个问题Ordering吗?

对我没有帮助的相关问题

标签: multithreadingrustatomic

解决方案


推荐阅读