这样的类只有一个Set由多个线程可读吗?

时间:2011-01-17 12:53:31

标签: c++ multithreading oop boost locking

所以有一个类:

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的线程实际获取数据(每个线程只有Get数据一次被调用Set(似乎就像只有第一个“读者”调用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;
};

2 个答案:

答案 0 :(得分:3)

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

此外,changed变量对您没有帮助;它只允许一个线程看到变化。删除它。

答案 1 :(得分:1)

实际上,在读者(notify_one())中调用Get是一种奇怪的方法!如果您希望读者等到某事已经确定,那么您需要这样的事情:

 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的调用将有效地等待状态发生有效更改。然而,这种方法(有条件)容易出现诸如虚假唤醒(应该由循环处理),丢失通知等问题。你需要找到一个更好的模型(所有大多数声音就像每个线程的队列一样) )。