如何保证一个成员函数在另一个成员函数之前获得 mutex?

查看 41|回复 6
作者:LcDraven   
假设有个类的两个成员函数,需要在不同的线程里执行,这两个成员函数需要写入同一个文件,因此需要使用 mutex 确保这两个函数不会同时写,代码类似这样
class Widget{
public:
    void funA();
    void funnB();
private:
    std::mutex mutex;
};
void Widget::funA(){
    {
        std::unique_lock(mutex);
        //operate A;
    }
}
void Widget::funB(){
    {
        std::unique_lock(mutex);
        //operate B;
    }
}
然后设计两个函数来封装这两个成员函数,类似
void execA(Widget* w){
    w->funcA();
};
最后程序里,生成一个 Widget 的对象,需要在两个线程里执行这两个函数,即
Widget* w{};
std::jthread threadA(execA, &w);  //在一个线程里执行 A 函数
std::jthread threadB(execB, &w);  //在另一个线程里执行 B 函数
在这种情况下,大多数式成员函数 funcA()先执行,但多次尝试后,有几次式 funcB()先获得 mutex 。
在下列三个前置条件下
[ol]
  • 使用 c++20 标准,并可以使用 vs2022 最新版支持的 c++23 标准
  • 不该用 std::thread
  • 不使用 std::this_thread::sleep_for()对 B 进行睡眠
    [/ol]
    我向问下,有没有办法确保 A 一定在 B 之前获得 mutex ?
  • billlee   
    用信号量控制两个线程的同步关系
    LcDraven
    OP
      
    你的需求是 threadB 在 threadA 后执行,这个不是 mutex 能解决的问题。请使用条件变量
    GeruzoniAnsasu   
    @billlee 他的场景用条件变量不是把简单问题复杂化了吗?用信号量最优吧我觉得,或者再用一个互斥锁也可以同步线程的同步关系,甚至用全局变量加互斥锁也可以。但是信号量是最简单最专业的吧
    billlee   
    https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange
    spinlock 的典型场景呗
    B 线程读 flag, A 线程写 flag
    jujusama   
    @LcDraven 嗯,对。Semaphore 更简单一点,刚才没想到
    billlee   
    在 Widget 的构造内将 mutex.lock(),在 function A 内使用 std::unique_lock(mutex, std::adopt_lock);
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部