我想演示/记录一些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
与包装器一起工作?
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
。
我知道互斥体通常也会保护共享数据,使用原子变量只是一个例子。问题不是如何保护共享数据,而是是否需要使用相同的互斥体来保护两者。另一个使用第二互斥体的示例:
我在理解条件变量及其在互斥体中的使用时遇到了一些困难,我希望社区能帮助我。请注意,我来自win32背景,因此与CRITICAL_SECTION、HANDLE、SetEvent、WaitForMultipleObject等一起使用。 这是我第一次尝试使用C++11标准库进行并发操作,它是在这里找到的一个程序示例的修改版本。 关于这个的几个问题。 我读过“任何要等待std::condition_var
我需要弄清楚lock和condition_variable是如何工作的。 在这里略有修改的cplusplusreference代码中 我感到困惑的是,如果worker_thread已经锁定了互斥体,主线程如何锁定它。 我不明白为什么在这种情况下会出现“运行时错误”。
我不明白的是,当condition_variable和互斥体之间没有任何链接的时候,为什么所有4个线程都可以在互斥体上获得锁?
我试图在我自己的包中使用data.table包。MWE如下: