【问题标题】:unlocking threads only on new data (threads calling order)仅在新数据上解锁线程(线程调用顺序)
【发布时间】:2011-01-17 12:00:07
【问题描述】:

所以我有一个像这样的课程:

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,还有3 个线程在循环中调用Get。我需要让我的线程Get 一次和平数据不超过一次(这意味着它不能像我们Set 一样快地调用Get,这没关系,但它不能多次调用它 unteel new @ 987654327@ 被调用)。我的意思是在调用Get 的线程之后,它不能访问Get unteel Set 被执行。如何在如此简单的类中实现这样的事情,或者我的锁会默认为我做吗?

【问题讨论】:

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


    【解决方案1】:

    您需要condition variable

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

    这需要改进,但可以完成工作。我通常会使用一个 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;
    };
    

    【讨论】:

    • 我们有很多读者,所以我需要一些一旗之王。如果读者没有时间阅读已设置的内容,那也没关系。
    • 我已经完成了一个确保每个集合都被读取的实现。如果你不需要,你可以只写一个未读的值,那么上面的 Set() 函数不需要等待条件变量,Get() 函数不需要发出信号。
    • hm... 当我们设置 changed = false; // 为一个阅读器线程标记为已读,它不会为所有其他阅读器设置它吗?我的意思是不会发生这样的情况,只有一个读者会得到数据?
    • 当我们设置 changed = false 时,它​​将被标记为已读,因此所有读者都会知道它已被读取,并且只有一个人会真正“获取”它。这里的“改变”反映了班级的状态。
    • 以及如何让所有阅读器都能够阅读或阅读数据(但只有一次Set)?你可以在这里发布答案stackoverflow.com/questions/4713357/…
    【解决方案2】:

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

    【讨论】:

    • 你的意思是我们不能在这个类级别上实现等待,而只能在我们创建线程的级别上实现?或者如果可以在此类级别上完成,请提供一些与我提供的示例更相关的代码 - (对不起,我正在处理 nube)
    猜你喜欢
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 2016-08-07
    • 2012-05-08
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多