Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用boost可升级互斥体的示例_C++_Boost Thread_Boost Interprocess - Fatal编程技术网

C++ 如何使用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

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

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

很多时候我只是在看地图。 但是,我也需要偶尔补充一下

e、 g。 typedef std::map MessageMap; MessageMap-msgmap; boost:共享互斥访问

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