如何使用boost可升级互斥锁的示例

Mat*_*att 7 c++ boost-thread boost-interprocess

我有一个多线程服务器应用程序,需要在某些共享内存上进行互斥锁定.

共享内存基本上是sTL地图等.

很多时候我只是从地图上读书.但是,我还需要偶尔添加它.

例如typedef std :: map MessageMap; MessageMap msgmap; 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.
}
Run Code Online (Sandbox Code Playgroud)

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

什么是共享/升级和独家之间的区别.即我不明白这个解释.听起来好像只是想要允许大量读者,您只想获得共享访问权限.要写入共享内存,您只需要升级访问权限.或者您需要独家吗?在提升中的解释是明确的.

是否可以编写升级访问权限.但共享意味着你绝对不会写就是这意味着什么?

编辑:让我以更清晰的方式解释我想要做的事情.我对答案还不满意.

这是一个重复的例子,但是我正在使用一些代码的例子.只是一个例子,而不是实际的代码.

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?
    }
Run Code Online (Sandbox Code Playgroud)

ybu*_*ill 11

你说你的应用程序是多线程的,所以你应该使用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..
Run Code Online (Sandbox Code Playgroud)

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

编辑:我认为提升中的解释明确的.无论如何,让我们试着改写一下:

有三种主要类型的互斥锁概念(我不计算TimedLockable,因为它与您的问题无关):

  • 可锁定 - 只是一个简单的,独占的互斥锁.如果有人锁定()s没有人可以再次锁定()它,直到所有者解锁()它.boost :: thread :: mutex实现了这个概念.要以RAII样式锁定此概念,请使用lock_guard或unique_lock来获得更复杂的接口.
  • SharedLockable - 具有额外"共享"所有权的可锁定.您可以使用lock()获得独占所有权,或使用lock_shared()获得共享所有权.如果您锁定共享部分,则无法将所有权升级为独占部分.你需要再次unlock_shared()和lock(),这意味着其他人可能会修改unlock_shared()和lock()之间的受保护资源.当您事先了解对资源的访问权限时,它非常有用.shared_mutex实现了这个概念.使用lock_guard或unique_lock获取独占所有权,使用shared_lock获取共享所有权.
  • UpgradeLockable - 是SharedLockable,允许您从共享所有权升级到独占所有权而无需解锁.shared_mutex也实现了这个概念.您可以使用上述锁获得独占或共享所有权.要获得可升级的共享所有权,请使用upgrade_lock并使用upgrade_to_unique_lock进行升级.


Sam*_*ler 5

boost-interprocess如果您只是使用单个流程,则不需要.正如库名所暗示的那样,它用于进程间通信(IPC).您最有可能想要使用boost-thread 互斥锁和锁定概念.

#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
    }
}
Run Code Online (Sandbox Code Playgroud)

在boost邮件列表上有一篇文章解释了这一点.