C++ boost shared_互斥体示例(多读/一写)?
我有一个多线程应用程序,它必须经常读取一些数据,并且偶尔会更新这些数据。现在,互斥锁可以确保对数据的访问安全,但代价很高,因为我希望多个线程能够同时读取数据,并且只在需要更新时将其锁定(更新线程可以等待其他线程完成) 我认为这就是C++ boost shared_互斥体示例(多读/一写)?,c++,multithreading,boost,mutex,boost-thread,C++,Multithreading,Boost,Mutex,Boost Thread,我有一个多线程应用程序,它必须经常读取一些数据,并且偶尔会更新这些数据。现在,互斥锁可以确保对数据的访问安全,但代价很高,因为我希望多个线程能够同时读取数据,并且只在需要更新时将其锁定(更新线程可以等待其他线程完成) 我认为这就是boost::shared_mutex应该做的,但我不清楚如何使用它,也没有找到一个明确的例子 有没有人可以用一个简单的例子来开始呢?看起来你会这样做: boost::shared_mutex _access; void reader() { // get shar
boost::shared_mutex
应该做的,但我不清楚如何使用它,也没有找到一个明确的例子
有没有人可以用一个简单的例子来开始呢?看起来你会这样做:
boost::shared_mutex _access;
void reader()
{
// get shared access
boost::shared_lock<boost::shared_mutex> lock(_access);
// now we have shared access
}
void writer()
{
// get upgradable access
boost::upgrade_lock<boost::shared_mutex> lock(_access);
// get exclusive access
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
// now we have exclusive access
}
boost::共享互斥访问;
无效读取器()
{
//获取共享访问权限
boost::共享锁定(访问);
//现在我们有了共享访问权限
}
空写器()
{
//获取可升级访问
boost::升级\u锁(\u访问);
//获得独占访问权
boost::将_升级为_unique _lockuniquelock(锁);
//现在我们有独家访问权
}
使用计数等于读卡器数量的信号量。让每个读卡器对信号量进行一次计数以便读取,这样他们就可以同时读取。然后让编写器在写入之前获取所有信号量计数。这会导致写入程序等待所有读取完成,然后在写入时阻止读取。1800信息或多或少是正确的,但有几个问题我想纠正
boost::shared_mutex _access;
void reader()
{
boost::shared_lock< boost::shared_mutex > lock(_access);
// do work here, without anyone having exclusive access
}
void conditional_writer()
{
boost::upgrade_lock< boost::shared_mutex > lock(_access);
// do work here, without anyone having exclusive access
if (something) {
boost::upgrade_to_unique_lock< boost::shared_mutex > uniqueLock(lock);
// do work here, but now you have exclusive access
}
// do more work here, without anyone having exclusive access
}
void unconditional_writer()
{
boost::unique_lock< boost::shared_mutex > lock(_access);
// do work here, with exclusive access
}
boost::共享互斥访问;
无效读取器()
{
boost::shared_locklock(_访问);
//在这里工作,任何人都不能独占
}
void条件_writer()
{
boost::升级锁锁(\u访问);
//在这里工作,任何人都不能独占
如果(某物){
boost::升级到唯一锁唯一锁(锁);
//请在这里工作,但现在您拥有独占访问权限
}
//在这里做更多的工作,没有任何人拥有独占访问权限
}
void无条件的(u writer)
{
boost::unique_locklock(_访问);
//在这里工作,拥有专属访问权限
}
还要注意的是,与共享_锁不同的是,一次只有一个线程可以获得升级_锁,即使它没有升级(当我遇到它时,我觉得很尴尬)。因此,如果你的读者都是有条件的编写者,你需要找到另一个解决方案。为了添加更多的经验信息,我一直在研究可升级锁的整个问题,添加一个重要信息是一个很好的答案,即即使没有升级,也只有一个线程可以拥有升级锁,这很重要,因为这意味着如果不先释放共享锁,就无法从共享锁升级到唯一锁。(这已经在别处讨论过了,但最有趣的线索在这里) 然而,我确实发现线程等待升级到锁(即需要等待所有读卡器释放共享锁)和写入器锁等待相同的东西(即唯一的锁)之间有一个重要的(未记录的)区别
这是一个需要考虑的重要问题,应该有记录。
< P>自从C++ 17(VS2015)你可以使用读写锁的标准:< /P>#include <shared_mutex>
typedef std::shared_mutex Lock;
typedef std::unique_lock< Lock > WriteLock;
typedef std::shared_lock< Lock > ReadLock;
Lock myLock;
void ReadFunction()
{
ReadLock r_lock(myLock);
//Do reader stuff
}
void WriteFunction()
{
WriteLock w_lock(myLock);
//Do writer stuff
}
#包括
typedef std::共享互斥锁;
typedef std::unique_lockWriteLock;
typedef std::shared_lockReadLock;
锁定myLock;
void ReadFunction()
{
ReadLock r_lock(myLock);
//做读者的事
}
void WriteFunction()
{
写锁w_锁(myLock);
//做作家的工作
}
对于旧版本,可以使用具有相同语法的boost:
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
typedef boost::shared_mutex Lock;
typedef boost::unique_lock< Lock > WriteLock;
typedef boost::shared_lock< Lock > ReadLock;
#包括
#包括
typedef boost::共享互斥锁;
typedef boost::unique_lockWriteLock;
typedef boost::shared_lockReadLock;
吉姆·莫里斯(Jim Morris)的回应很好,我偶然发现了这一点,花了一段时间才想明白。下面是一些简单的代码,它表明在提交一个“请求”以获得唯一的锁定增强(1.54版)后,会阻止所有共享锁定请求。这是非常有趣的,因为在我看来,如果我们想要写优先级或没有优先级,在唯一的_锁和可升级的_锁之间进行选择是允许的
吉姆·莫里斯的帖子似乎与此相矛盾:
#包括
#包括
使用名称空间std;
typedef boost::共享互斥锁;
typedef boost::unique_lockUniqueLock;
typedef boost::shared_lockSharedLock;
锁模锁;
void main 2(){
这是我第一次使用Boost,我是C++新手,所以可能有一些东西我丢失了——但是在我自己的代码中,我必须指定类型,比如:Booo::SysDyLoCK锁(Access);我试图自己使用它,但我遇到了一个错误。在“lock”之前缺少模板参数。有什么想法吗?@shaz这些是有范围的,但您可以使用.unlock()提前释放它们如果需要的话。我已经添加了缺少的模板参数。@raaj您可以获得升级锁,但升级到唯一锁将被阻止,直到释放共享锁调整到“另一个解决方案”上的注释.当我所有的读者都是条件编写器时,我所做的是让他们总是获得一个共享的_锁,当我需要升级到编写特权时,我会.unlock()读卡器锁定并获取一个新的唯一锁定。这将使应用程序的逻辑复杂化,并且现在有机会让其他编写器更改您第一次读取时的状态。行boost::unique\u locklock(lock);
readboost::unique\u locklock不是应该吗(
\u访问#include <iostream>
#include <boost/thread.hpp>
using namespace std;
typedef boost::shared_mutex Lock;
typedef boost::unique_lock< Lock > UniqueLock;
typedef boost::shared_lock< Lock > SharedLock;
Lock tempLock;
void main2() {
cout << "10" << endl;
UniqueLock lock2(tempLock); // (2) queue for a unique lock
cout << "11" << endl;
boost::this_thread::sleep(boost::posix_time::seconds(1));
lock2.unlock();
}
void main() {
cout << "1" << endl;
SharedLock lock1(tempLock); // (1) aquire a shared lock
cout << "2" << endl;
boost::thread tempThread(main2);
cout << "3" << endl;
boost::this_thread::sleep(boost::posix_time::seconds(3));
cout << "4" << endl;
SharedLock lock3(tempLock); // (3) try getting antoher shared lock, deadlock here
cout << "5" << endl;
lock1.unlock();
lock3.unlock();
}