我知道在C++14中可以使用boost::UpgradeLockable
实现此功能。
那么在C++11中是否有类似的方法呢?
可升级锁可以在更简单的锁原语之上编写。
struct upgradeable_timed_mutex {
void lock() {
upgradable_lock();
upgrade_lock();
}
void unlock() {
upgrade_unlock();
upgradable_unlock();
}
void shared_lock() { shared.shared_lock(); }
void shared_unlock() { shared.shared_unlock(); }
void upgradable_lock() { unshared.lock(); }
void ungradable_unlock() { unshared.unlock(); }
void upgrade_lock() { shared.lock(); }
void upgrade_unlock() { shared.unlock(); }
private:
friend struct upgradable_lock;
std::shared_timed_mutex shared;
std::timed_mutex unshared;
};
对于定时和尝试变体,类似的操作。请注意,连续访问两个互斥锁的定时变体必须进行一些额外的工作,以避免花费多达2倍所请求的时间,并且try_lock
必须小心第一个锁的状态,以防第二个失败。
然后,您需要编写upgradable_lock
,并能够根据需要生成std::unique_lock
。
自然而然地,这是手写的线程安全代码,因此可能不正确。
在C++1z中,您还可以编写无定时版本(使用std::shared_mutex
和std::mutex
)。
不太具体地说,一次只能有一个可升级或写锁。这就是unshared
互斥锁所代表的。
只要持有unshared
,没有其他人会写入受保护的数据,因此您可以在根本不持有共享互斥锁的情况下从中读取。
当您想要升级时,可以在共享互斥锁上获取唯一锁。只要没有读者尝试升级到可升级状态,这样做就不会死锁。这将排除读者的阅读,您可以编写,然后释放它并返回到只读状态(在此状态下,您仅持有未共享的互斥锁)。
shared
互斥锁的shared_lock
,然后寻求一个唯一的互斥锁。这种情况下,第二个互斥锁unshared
将是多余的,或者我漏掉了什么? - Richard Hodges
std
中一样高效地完成任务,那么我们是否应该将其放入std
中?也许可以考虑。 - Yakk - Adam Nevraumontshared_mutex
很多年了,并且只需要C++98。 - Arne Vogel