【问题标题】:Would such class be readable only once a Set by multiple threads?这样的类只能由多个线程读取一次吗?
【发布时间】:2011-01-17 12:53:31
【问题描述】:

所以有这样的课程:

class mySafeData
{
public:
  mySafeData() : myData(0), changed( false )
  {
  }

  void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    myData = i; // set the data
    changed = true; // mark as changed
    myCondvar.notify_one(); // notify so a reader can process it
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    while( !changed )
    {
       myCondvar.wait( lock );
    } 
    i = myData;
    changed = false; // mark as read
    myCondvar.notify_one(); // notify so the writer can write if necessary
  }
 private:
   int myData;
   boost::mutex myMutex;
   boost::condition_variable myCondvar;
   bool changed;
};

循环中的一个线程调用Set。以及 3 个或更多线程调用 Get 如何使所有线程调用 Get 以实际获取数据(每个线程应仅在调用 SetGet 数据)(似乎只有第一个调用的“读者” Get 获取数据)?

更新会这样吗?:

class mySafeData
{
public:
  mySafeData() : myData(0)
  {
  }

  void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    myData = i; // set the data
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    i = myData;

  }
 private:
   int myData;
   boost::mutex myMutex;
};

【问题讨论】:

    标签: c++ multithreading oop boost locking


    【解决方案1】:

    我认为你不需要条件变量;互斥量应该足够了。

    另外,changed 变量对您没有帮助;它只允许一个线程看到更改。也将其删除。

    【讨论】:

    • 我更新了帖子 - 你的意思是我发布的更新会起作用吗?我的主要观点是读者不要在一组中阅读超过一次......
    • 我想这会起作用(尽管您可能需要将 myData 声明为 volatile 以防止编译器进行不安全的优化。我不确定您所说的“阅读不阅读更多信息”是什么意思每组不止一次”。您肯定只是希望get() 在每次阅读器线程调用它时安全地返回最新值吗?
    【解决方案2】:

    实际上,在阅读器(Get)中调用notify_one() 是一种奇怪的方法!如果您希望您的读者等到某些东西已经设置好,那么您需要这样的东西:

     void Set(int i) 
      {
        boost::mutex::scoped_lock lock(myMutex);
        myData = i; // set the data
        ++stateCounter;  // some int to track state chages
        myCondvar.notify_all(); // notify all readers
      }
    
      void Get( int& i)
      {
        boost::mutex::scoped_lock lock(myMutex);
        // copy the current state
        int cState = stateCounter;
        // waits for a notification and change of state
        while (stateCounter == cState)
          myCondvar.wait( lock );
      }
    

    现在对Get 的调用将有效地等待状态有效更改。然而,这种方法(有条件)容易出现诸如虚假唤醒(应该由循环处理)、丢失通知等问题。您需要为此找到更好的模型(所有听起来都像是每个线程队列的情况)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      相关资源
      最近更新 更多