2016-03-03 114 views
1

我需要使用挥发性多重映射迭代,但是迭代器的运营商(如++),当它被定义为挥发性不工作...如何使用volatile多图迭代器?

首先:为什么需要挥发性迭代器(和不是一个可变的)?

我写了一个实用程序类(Echeancier),它必须安排按日期排序的截止日期列表(Echeance)。 所有截止日期都存储在一个multimap中,其关键是截止日期(_echeancesParDate)。

每个截止日期是连续管理的,只有一个linux定时器: - 当定时器到期时,它会产生一个信号; - 信号的处理程序处理与截止日期相关的事件,然后在下一个最后期限重新启动计时器。

所以我需要在信号处理程序中使用typeListeEcheancesParDate :: iterator _comingEcheance。

另一方面,类Echeancier还定义了一个函数来创建新的截止日期(ajouterEcheance())。 此函数可能会更新_comingEcheance。

这就是为什么我需要将_comingEcheance定义为volatile。

注:目前,我把原子访问方面放在一边。

我的源代码(部分):

class Echeancier 
    { 

     private: 
     typedef std::multimap<Echeance::typeDateEcheance, Echeance*> typeListeEcheancesParDate; 

     typeListeEcheancesParDate _echeancesParDate; 

     typeListeEcheancesParDate::iterator volatile _comingEcheance; 

     void handlerEcheance(Echeance::typeEvenementEcheance eventEcheance); 

     AsyncTimer<Echeancier>* _timer; 
     int _numSignalTimer; 

     protected: 
     Echeancier(int signalEcheance); 
     ~Echeancier(); 

     virtual void traiterEvenement(Echeance::typeEvenementEcheance eventEcheance) = 0; 

     int ajouterEcheance(Echeance::typeDateEcheance date, 
        Echeance::typeEvenementEcheance evenement, 
        Echeance::typeIdentifiantEcheance & idEcheance); 
     int supprimerEcheance(Echeance::typeIdentifiantEcheance idEcheance); 
    } 

我唯一的想法是过载多重映射迭代++运算符,使其可与挥发性改性剂...... 但我不知道如何做到这一点...任何想法我的问题? 谢谢

+5

对我来说,除了硬件寄存器以外的其他东西都是“难闻的”......为什么代码首先使用volatile?当然,如果其他线程可以操作它们,则需要适当的锁定以防止另一个线程通过修改列表来扰乱当前线程工作......并且通过适当的锁定,不需要volatile。 –

+0

谢谢你的回答。 – petitponey

+0

谢谢你的回答。但是我不会在多线程上下文中使用此代码;我需要一个易变的变量,因为这个迭代器在信号处理函数中被修改;这个处理函数可以在程序中的任意位置异步调用,这是不可预知的:它是主程序外部的代理(就像硬件中断一样)。 – petitponey

回答

1

所以,我发表评论说,volatile是多线程环境中的一种难闻的气味,我坚持这一点。

在信号处理程序中处理数据也是一种难闻的气味。使用锁也不适用于信号处理程序,因为没有其他线程可以解锁程序主线程所持有的锁。

我认为你需要重新考虑你的整个设计,并使用两个线程[其中一个线程可以由定时器信号处理程序控制,并且具有高优先级]。重点在于操纵迭代器和迭代器指向的数据必须以原子方式处理,并且只标记volatile并不能解决这个问题 - volatile只意味着编译器必须“完成代码所要做的事情“ - 但这并不意味着你的数据本身是安全的。