C++ 中具有所有同步方法的类

use*_*858 7 c++ multithreading c++98

在Java中我们可以创建一个类

class Test {
    public synchronized void  fn1() {

    }

    public synchronized void  fn2() {

    }

    public synchronized void  fn3() {
        fn1(); // Calling another method
    }
}
Run Code Online (Sandbox Code Playgroud)

在 C++ 中,如果我想模仿功能,一种方法是

class Test {
    private:
        mutex obj;
    public:
       void fn1(bool calledFromWithinClass = false) {
            if(calledFromWithinClass) 
                fn1Helper();
            else
                unique_lock<mutex> lock(obj);
                fn1Helper();
        }

       void fn2(bool calledFromWithinClass = false) {
            if(calledFromWithinClass) 
                fn2Helper();
            else
                unique_lock<mutex> lock(obj);
                fn2Helper();
        }

        void fn3(bool calledFromWithinClass = false) {
            if(calledFromWithinClass) 
                fn3Helper();
            else {
                unique_lock<mutex> lock(obj);
                fn3Helper();
            } 
        }
    private:
        void fn1Helper() {
        }

        void fn2Helper() {
        }

        void fn3Helper() {
             fn1(true);
        }
}
int main() {
    Test obj;
    obj.fn1();
    obj.fn2(); 
    // i.e from outside the class the methods are called with calledFromWithinClass as false.
}
Run Code Online (Sandbox Code Playgroud)

简而言之,我想做的就是使用 RAII 进行锁定并允许函数相互调用。在没有 CalledFromWithinClass 标志的 C++ 中,如果外部函数已获取锁,则内部函数无法获取锁并且代码会卡住。

正如你所看到的,代码很复杂,有没有其他方法可以在 C++ 中做到这一点。

我只能使用C++98,你可以假设类中的所有方法都是同步的(即需要锁)

Ant*_*vin 8

我可以建议两个选择:

  1. 只需使用boost::recursive_mutex(或std::recursive_mutex在 C++11 中)即可。

  2. (更好)始终从同步代码中调用非同步私有实现:

    class Test {
    private:
        mutex obj;
    public:
       void fn1() {
            unique_lock<mutex> lock(obj);
            fn1Helper();
        }
    
       void fn2(bool calledFromWithinClass = false) {
            unique_lock<mutex> lock(obj);
            fn2Helper();
        }
    
    private:
        void fn1Helper() {
        }
    
        void fn2Helper() {
            fn1Helper();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)