我想知道boost::shared_mutex
和boost::upgrade_mutex
的区别是什么。我想做一个多线程的应用程序,将有多个频繁的读者和一个非频繁的作者。
我可以只使用标准的shared_mutex
和shared_lock
和unique_lock
。虽然这可能会给予我的作家挨饿。
我想要的是:如果一个读取器有一个共享锁,并且一个写入器正在等待这个锁,那么其他读取器将不会被授予访问权限,它们将不得不等待这个共享锁。boost::upgrade_mutex
上我能找到的信息很少,但我想这就是我想要的?
我做了这个例子(请忽略cout
是在锁等之外发生的,我无法控制哪个线程先运行):
#include <iostream>
#include <thread>
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
int main()
{
boost::shared_mutex mutex;
boost::shared_lock<boost::shared_mutex> read_lock(mutex);
std::thread t1([&mutex]()
{
std::cout << "Thread trying to get the unique lock!" << std::endl;
boost::unique_lock<boost::shared_mutex> write_lock(mutex);
std::cout << "Thread got the unique lock!" << std::endl;
});
std::thread t2([&mutex]()
{
std::cout << "Thread trying to get the shared lock!" << std::endl;
boost::shared_lock<boost::shared_mutex> read_lock(mutex);
std::cout << "Thread got the shared lock!" << std::endl;
});
// To make sure the threads ask for the lock before unlocking
sleep(1);
std::cout << "Unlocking first lock" << std::endl;
read_lock.unlock();
t1.join();
t2.join();
}
从我的测试来看,如果t1
在t2
之前运行,那么t2
也会在read_lock.unlock();
之前等待,这就是我想要的!
然后我把boost::upgrade_mutex
修改为boost::shared_mutex
(也在锁的模板参数中),我看到了完全相同的行为。我在文档中找不到这是否有保证,或者有什么区别。
1条答案
按热度按时间2q5ifsrm1#
阅读文档后,upgrade_mutex是一个shared_mutex,具有考虑升级的额外功能。https://www.boost.org/doc/libs/1_81_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.upgrade_lockable
UpgradeLockable概念是SharedLockable概念的改进,它允许可升级所有权以及共享所有权和独占所有权。这是对SharedLockable概念提供的多读取器/单写入模型的扩展:单个线程可以在其他线程具有共享所有权的同时具有可升级所有权。具有可升级所有权的线程可以在任何时候尝试将该所有权升级为独占所有权。如果没有其他线程具有共享所有权,则升级立即完成,并且该线程现在具有独占所有权,必须通过调用unlock来放弃该独占所有权(),就好像它是通过调用lock()获取的一样。
shared_lock不能做的事情是从共享锁升级到唯一锁,而不解锁。upgrade_lock介于共享锁和唯一锁之间。您只能有一个升级锁,但同时可以使用多个共享锁。您可以要求将升级锁升级到唯一锁。只有在所有的共享锁都被释放之后,它才会成功。(其他操作也是可能的,尽管它们与理解差异不太相关)