Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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 shared_互斥体示例(多读/一写)?_C++_Multithreading_Boost_Mutex_Boost Thread - Fatal编程技术网

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);
    read
    boost::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(); }