这样的类只能由多个线程一次读取一次吗? [英] Would such class be readable only once a Set by multiple threads?

查看:56
本文介绍了这样的类只能由多个线程一次读取一次吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以有一个像这样的类:

So having a class like:

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的线程实际获取数据(每个线程仅在Set被调用后才Get数据)(似乎只有第一个读取器"调用Get获取数据)?

And one thread in loop calling Set. And 3 or more threads calling Get how to make all threads calling Get to actually get data (each thread shall Get data only once a Set was called)(it seems like only first "reader" who calls Get gets data)?

这会更新吗?:

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

推荐答案

实际上,在阅读器(Get)中调用notify_one()是一种奇怪的方法!如果您希望读者等到设置完成后,就需要这样的东西:

Actually, It's an odd approach to call notify_one() in the reader (Get)! If you want your readers to wait till something has been set, then you need something like this:

 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的调用将有效地等待,直到状态发生有效改变为止.但是,这种方法(带有条件)易于出现诸如虚假唤醒(应由循环处理),丢失通知等问题.您需要为此找到一个更好的模型(所有听起来像每个线程都有一个队列的情况) ).

Now a call to Get will effectively wait till there is a valid change of state. However this approach (with conditions) is prone to issues such as spurious wakeups (which should be handled by the loop), lost notifications etc. You need to find a better model for this (all most sounds like a case of a queue per thread).

这篇关于这样的类只能由多个线程一次读取一次吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆