首页 > 解决方案 > 使用条件变量的 C++ 监视类/包装器

问题描述

我试图W在 C++ 中创建一个包装类,它是用指向通用对象的指针构造的OBJ

当您通过 调用其中一个OBJ方法时WW(包含条件变量cv)会发出一个cv.wait()调用前OBJ方法和一个cv.notify()何时OBJ方法完成。

我已经能够通过继承特定类来做到这一点,但想要一种像上面描述的通用方法。

这是继承方法:

struct A
{
    virtual void foo(int i) { bar = i; };
    int bar;
};

struct B : public A
{
    void foo2(int i)
    {
        cv.wait(lck);
        this->foo(i);
        cv.notify_one();
    }
    std::condition_variable cv;
    std::unique_lock<std::mutex> lck;
};

我想要类似的东西:

template<class T>
struct C
{
    C(T *t) : t(t) {}

    T *operator->()
    {
        cv.wait(lck);
        return t;
        // notify_one when function has completed
    }

    T *t;
    std::condition_variable cv;
    std::unique_lock<std::mutex> lck;
};

我只使用锁找到了答案(但这并不是真正的监视器):https ://stackoverflow.com/a/48408987

标签: c++concurrencymonitor

解决方案


这是一个工作示例:

#include <iostream>
#include <mutex>

template<class T>
class Wrapper {
    std::mutex m;
    T* p;

public:
    Wrapper(T& t) : p(&t) {}

    class Proxy {
        std::unique_lock<std::mutex> lock;
        T* p;

    public:
        Proxy(std::mutex& m, T* p)
            : lock(m)
            , p(p)
        {
            // Locked the mutex.
            std::cout << __PRETTY_FUNCTION__ << '\n';
        }

        Proxy(Proxy&& b) = default;

        ~Proxy() {
            std::cout << __PRETTY_FUNCTION__ << '\n';
            // Unlocked the mutex.
        }

        T* operator->() const { return p; }
    };

    Proxy operator->() { return Proxy(m, p); }
};

struct A {
    void f() { std::cout << __PRETTY_FUNCTION__ << '\n'; }
};

int main() {
    A a;
    Wrapper<A> w(a);
    w->f();
}

输出:

Wrapper<T>::Proxy::Proxy(std::mutex&, T*) [with T = A]
void A::f()
Wrapper<T>::Proxy::~Proxy() [with T = A]

有关完整详细信息,请参阅Bjarne Stroustrup 的 Wrapping C++ Member Function Calls 。


推荐阅读