仅在新数据上解锁线程(线程调用顺序)

时间:2011-01-17 12:00:07

标签: c++ multithreading boost locking getter-setter

所以我有一个类:

class mySafeData
{
public:
    void Set(int i) {
        boost::mutex::scoped_lock lock(myMutex);
        myData = i;
    }
    void Get( int& i)
    {
        boost::mutex::scoped_lock lock(myMutex);
        i = myData;
    }
private:
    int myData;
    boost::mutex myMutex;

};

我有一些在循环中调用Set的线程和在循环中调用Get的3个线程。我需要让我的帖子Get一次数据和平不超过一次(这意味着它不能像我们Get那样快地调用Set,这是可以的,但它不会称之为不止一次unteel新Set被召唤)。我的意思是在称为Get的线程之后,它无法访问Get unteel Set被执行。如何在这样简单的类中实现这样的东西,或者默认情况下我的锁会为我做这件事吗?

2 个答案:

答案 0 :(得分:2)

您需要condition variable

请注意,即使读者线程获取与条件变量关联的互斥锁,也需要检查条件是否已满足。也许让setter在设置了某个东西时设置了一个标志,读者可以在读取它时重置它。

这需要改进,但会完成这项工作。我通常会使用std :: deque,因此编写者可以编写必须锁定但无需等待线程读取它。

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

  void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    while( changed )
        myCondvar.wait( lock ); // wait for the data to be read

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

答案 1 :(得分:1)

您需要使用conditional variable向对象线程发信号通知对象状态的变化。