C++ 如何使用boost可升级互斥体的示例
我有一个多线程服务器应用程序,需要在一些共享内存上使用互斥锁 共享内存基本上是sTL映射等 很多时候我只是在看地图。 但是,我也需要偶尔补充一下 e、 g。 typedef std::map MessageMap; MessageMap-msgmap; boost:共享互斥访问C++ 如何使用boost可升级互斥体的示例,c++,boost-thread,boost-interprocess,C++,Boost Thread,Boost Interprocess,我有一个多线程服务器应用程序,需要在一些共享内存上使用互斥锁 共享内存基本上是sTL映射等 很多时候我只是在看地图。 但是,我也需要偶尔补充一下 e、 g。 typedef std::map MessageMap; MessageMap-msgmap; boost:共享互斥访问 void ProcessMessage(Message* message) { // Access message... read some stuff from it message->... UU
void ProcessMessage(Message* message)
{
// Access message... read some stuff from it message->...
UUID id = message->GetSessionID();
// Need to obtain a lock here. (shared lock? multiple readers)
// How is that done?
boost::interprocess::scoped_lock(access_);
// Do some readonly stuff with msgmap
MessageMap::iterator it = msgmap.find();
//
// Do some stuff...
// Ok, after all that I decide that I need to add an entry to the map.
// how do I upgrade the shared lock that I currently have?
boost::interprocess::upgradable_lock
// And then later forcibly release the upgrade lock or upgrade and shared lock if I'm not looking
// at the map anymore.
// I like the idea of using scoped lock in case an exception is thrown, I am sure that
// all locks are released.
}
编辑:
我可能会混淆不同的锁类型
共享/升级和独占有什么区别。
i、 我不明白这个解释。
听起来,如果您只想允许大量的读者,那么您只想获得共享访问。要写入共享内存,只需升级访问权限。还是你需要独家的?boost中的解释一点也不清楚
已获得升级访问权限,因为您可能会写入。但共享意味着你肯定不会写,这就是它的意思吗
编辑:让我更清楚地解释一下我想做什么。我对答案还不满意
这里是一个例子,但与一些代码的例子,我也在使用。
只是一个说明,而不是实际的代码
typedef boost::shared_mutex Mutex;
typedef boost::shared_lock<Mutex> ReadLock;
typedef boost::unique_lock<Mutex> WriteLock;
Mutex mutex;
typedef map<int, int> MapType; // Your map type may vary, just change the typedef
MapType mymap;
void threadoolthread() // There could be 10 of these.
{
// Add elements to map here
int k = 4; // assume we're searching for keys equal to 4
int v = 0; // assume we want the value 0 associated with the key of 4
ReadLock read(mutex); // Is this correct?
MapType::iterator lb = mymap.lower_bound(k);
if(lb != mymap.end() && !(mymap.key_comp()(k, lb->first)))
{
// key already exists
}
else
{
// Acquire an upgrade lock yes? How do I upgrade the shared lock that I already have?
// I think then sounds like I need to upgrade the upgrade lock to exclusive is that correct as well?
// Assuming I've got the exclusive lock, no other thread in the thread pool will be able to insert.
// the key does not exist in the map
// add it to the map
{
WriteLock write(mutex, boost::adopt_lock_t()); // Is this also correct?
mymap.insert(lb, MapType::value_type(k, v)); // Use lb as a hint to insert,
// so it can avoid another lookup
}
// I'm now free to do other things here yes? what kind of lock do I have here, if any? does the readlock still exist?
}
typedef boost::shared_mutex mutex;
typedef boost::共享_锁ReadLock;
typedef boost::unique_lock WriteLock;
互斥互斥;
typedef映射映射类型;//您的地图类型可能会有所不同,只需更改typedef即可
地图类型mymap;
void threadoolthread()//可能有10个。
{
//在此处添加要映射的元素
int k=4;//假设我们正在搜索等于4的键
int v=0;//假设我们希望值0与键4关联
ReadLock read(mutex);//这是否正确?
迭代器lb=mymap.lower_-bound(k);
如果(lb!=mymap.end()&&!(mymap.key_comp()(k,lb->first)))
{
//密钥已存在
}
其他的
{
//获取升级锁是吗?如何升级已拥有的共享锁?
//我想我需要将升级锁升级为独占锁,对吗?
//假设我拥有独占锁,线程池中没有其他线程能够插入。
//该键在地图中不存在
//把它添加到地图上
{
WriteLock write(互斥,boost::采用_lock_t());//这也是正确的吗?
插入(lb,MapType::value_type(k,v));//使用lb作为插入的提示,
//因此,它可以避免另一次查找
}
//我现在可以在这里做其他事情了是吗?我这里有什么类型的锁,如果有的话?readlock还存在吗?
}
您说过您的应用程序是多线程的,所以应该使用boost::thread而不是boost::interprocess
根据文档(未经测试),您应该这样做:
typedef boost::thread::shared_mutex shared_mutex;
boost::thread::upgrade_lock<shared_mutex> readLock(access_);
// Read access...
boost::thread::upgrade_to_unique_lock<shared_mutex> writeLock(readLock);
// Write access..
typedef boost::thread::shared_mutex shared_mutex;
boost::thread::升级\u锁readLock(访问);
//读访问。。。
boost::thread::将_升级为_unique _lockwritelock(readLock);
//写访问。。
另请注意,您在锁定读取访问权限时获取了it
,因此有人可能会删除此节点,当您进入写入部分时,此节点不再有效。错误,抱歉
编辑:我认为boost中的这一点很清楚。不管怎样,让我们试着重新表述一下:
有三种主要类型的互斥概念(我不计算TimedLockable,因为它与您的问题无关):
- 可锁定的-只是一个简单的独占所有权互斥锁。如果有人锁定它,在所有者解锁它之前,没有人可以再次锁定它。boost::thread::mutex实现了这个概念。要以RAII样式锁定这个概念,请使用lock\u guard或unique\u lock来实现更复杂的接口
- SharedLockable-是一种可锁定的,具有额外的“共享”所有权。您可以使用lock()或lock_shared()获得独占所有权。如果锁定共享部分,则无法将所有权升级为独占部分。您需要解锁_shared()和lock()同样,这意味着其他人可能会在unlock_shared()和lock()之间修改受保护的资源。当您事先知道您将对资源进行何种访问时,这很有用。shared_mutex实现了这一概念。使用lock_guard或unique_lock获得独占所有权,使用shared_lock获得共享所有权
- UpgradeLockable-是SharedLockable,允许您在不解锁的情况下从共享所有权升级到独占所有权。共享互斥体也实现了这一概念。您可以使用上述锁获取独占或共享所有权。要获取可升级的共享所有权,请使用upgrade\u lock并使用upgrade\u升级到\u uniq你锁上了
增强进程间
。正如库名称所示,它用于进程间通信(IPC)。您很可能希望使用增强线程
#包括
#包括
int
main()
{
typedef boost::共享互斥体互斥体;
typedef boost::共享_锁ReadLock;
typedef boost::unique_lock WriteLock;
互斥互斥;
{
//获取读锁
读锁读(互斥);
//做一些事情来阅读资源
}
{
//获取写锁
WriteLock写入(互斥,boost::采用锁定);
//做点什么来编写资源
}
}
boost邮件列表上也有一个解释。对不起,我想也许我想使用boost::upgrade\u lock和boost::upgrade\u to\u unique\u lock。也许你可以解释它们之间的区别。请参阅我编辑的问题。UpgradeLockable只能有一个线程处于该状态,但有几个线程可以处于SharedLockable状态,对吗?因此,为了使升级锁成为唯一锁,所有共享锁都需要解锁,对吗?@Matt:“那里有可升级锁定…”只有一个处于唯一状态,许多处于可升级或shar状态
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
int
main()
{
typedef boost::shared_mutex Mutex;
typedef boost::shared_lock<Mutex> ReadLock;
typedef boost::unique_lock<Mutex> WriteLock;
Mutex mutex;
{
// acquire read lock
ReadLock read( mutex );
// do something to read resource
}
{
// acquire write lock
WriteLock write( mutex, boost::adopt_lock_t() );
// do something to write resource
}
}