gpt4 book ai didi

c++ - 如何使用 boost 可升级互斥量的示例

转载 作者:可可西里 更新时间:2023-11-01 18:16:38 26 4
gpt4 key购买 nike

我有一个多线程服务器应用程序,需要对一些共享内存进行互斥锁。

共享内存基本上是sTL映射等。

很多时候我只是在看 map 。但是,我也需要偶尔添加它。

例如 typedef std::map MessageMap; 消息映射 boost:shared_mutex access_;

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.
}

编辑:我可能会混淆不同的锁类型。

共享/升级和独占之间有什么区别。即我不明白这个解释。听起来,如果您只想允许大量读者,那么共享访问权限就是您想要获得的全部内容。要写入您的共享内存,您只需要升级访问权限。还是需要独家? 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?
}

最佳答案

你说你的应用程序是多线程的,所以你应该使用 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..

另请注意,您在锁定读取权限时获取 ,因此有人可能会删除此节点,并且当您到达写入部分时它不再有效。 错误,对不起。

编辑:我认为 explanation在 boost 中清楚的。无论如何,让我们试着重新表述一下:

互斥量概念主要分为三种(TimedLockable 不算在内,因为它与你的问题无关):

  • 可锁定 — 只是一个简单的独占所有权互斥锁。如果有人锁定()它,在所有者解锁()之前,没有人可以再次锁定()它。 boost::thread::mutex 实现了这个概念。要以 RAII 样式锁定此概念,请使用 lock_guard 或 unique_lock 以获得更复杂的接口(interface)。
  • SharedLockable — 是一个具有额外“共享”所有权的 Lockable。您可以使用 lock() 获得独占所有权或使用 lock_shared() 获得共享所有权。如果您锁定共享部分,您不能将您的所有权升级为专有部分。您需要再次 unlock_shared() 和 lock(),这意味着其他人可能会修改 unlock_shared() 和 lock() 之间的 protected 资源。当您先验地知道您将对资源进行何种访问时,它会很有用。 shared_mutex 实现了这个概念。使用 lock_guard 或 unique_lock 获取独占所有权,使用 shared_lock 获取共享所有权。
  • UpgradeLockable — 是 SharedLockable,它允许您在不解锁的情况下从共享所有权升级到独占所有权。 shared_mutex 也实现了这个概念。您可以使用上述锁来获得独占或共享所有权。要获得可升级的共享所有权,请使用 upgrade_lock 并使用 upgrade_to_unique_lock 对其进行升级。

关于c++ - 如何使用 boost 可升级互斥量的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3896717/

26 4 0