当前位置: 首页 > 知识库问答 >
问题:

如何使用std::condition_variable和我自己的互斥包装器

叶举
2023-03-14

我想演示/记录一些std::mutex行为。我希望记录对lock()unlock()的每个调用(不管它们是成功还是必须阻止)。最初,由于那些方法不是virtual,我尝试用以下方式包装标准的std::mutex,而不是使用继承:

struct mutex_wrapper {
    std::mutex mut = std::mutex();

    void lock() {
        std::cout << "LOCKING MUTEX\n";
        mut.lock();
    }

    void unlock() {
        std::cout << "UNLOCKING MUTEX\n";
        mut.unlock();
    }
};

忽略在多个线程中调用std::cout<<时,调用std::cout<<可能会产生损坏的输出。

然后,我想检查一个简单的std::condition_variable示例的输出,例如:

int main() {
    auto ready = false;
    auto mutex = mutex_wrapper();
    auto cvar = std::condition_variable();

    auto t = std::thread([&mutex, &cvar, &ready] {
        std::unique_lock lock(mutex);
        cvar.wait(lock, [&ready] { return ready; });
        std::cout << "woke up\n";
    });

    std::this_thread::sleep_for(std::chrono::seconds(2));
    {
        std::lock_guard lock(mutex);
        ready = true;
    }
    std::cout << "notifying\n";
    cvar.notify_one();

    t.join();
}

问题是它不能编译,因为wait()显然要求用常规的std::unique_lock实例化相应的std::mutex,而我试图将它与自己的mutex_wrapper一起使用。

有没有办法记录一个标准互斥体的锁定和解锁的内部使用情况?或者是否有方法使std::condition_variable与包装器一起工作?

共有1个答案

呼延烈
2023-03-14

std::condition_variable仅与std::unique_lock 一起工作--因此您可能希望使用std::condition_variable_any。这是std::condition_variable的泛化,可以使用任何basiclockable类型,例如互斥包装器。

请注意,直接使用std::condition_variable/std::mutex可能有点悲观,因为它们通常在实现中紧密耦合以获得更好的性能。但既然你已经在这里登录了,我怀疑这不会是一个很大的问题。

另一种方法是编写自己的自定义condition_variable包装器,该包装器直接根据包装的mutex类型和基础的std::condition_variable--并在锁定时直接提取std::mutex

 类似资料: