2016-03-03 3 views
1

Мне нужно использовать изменчивый многоадресный итератор, но операторы итератора (такие как ++) не работают, если он определен как volatile ...Как использовать изменчивый многоадресный итератор?

Прежде всего: зачем нужен летучий итератор (и НЕ изменчивый)?

Я пишу полезный класс (Echeancier), который должен запланировать список сроков (Echeance), упорядоченных по дате. Все предельные сроки хранятся в мультимаре, чей ключ является датой крайнего срока (_echeancesParDate).

Каждый конечный срок управляется последовательно, только с одним таймером Linux: - когда таймер истекает, он генерирует сигнал; - обработчик сигнала обрабатывает событие, связанное с крайним сроком, а затем перезапускает таймер для следующего крайнего срока.

Так что мне нужно использовать typeListeEcheancesParDate :: iterator _comingEcheance в обработчике сигналов.

С другой стороны, класс Echeancier также определяет функцию для создания новых сроков (ajouterEcheance()). Эта функция может обновлять _comingEcheance.

Вот почему мне нужно определить _comingEcheance как изменчивое.

NB: На данный момент я отложил атомный подход доступа.

Моего исходный код (частичный):

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

Единственная идея, у меня есть перегружать Multimap итератора оператора ++, чтобы сделать его работу с летучим модификатором ... Но я не знаю, как для этого ... любая идея для моей проблемы? Спасибо

+5

Для меня 'volatile' для чего-либо, кроме аппаратных регистров, является« неприятным запахом »... Почему код, использующий' volatile' в первую очередь? Конечно, если какой-то другой поток может ими манипулировать, вам нужны правильные блокировки, чтобы другой поток не испортил текущие потоки, изменив список ... И с правильными блокировками «volatile» не нужен. –

+0

Спасибо за ответ. – petitponey

+0

Спасибо за ответ.Но я не использую этот код в многопоточном контексте; Мне нужна переменная volatile, потому что этот итератор модифицируется в функции обработчика сигнала; эта функция обработчика может быть вызвана асинхронно, в любой точке программы, непредсказуемо: это агент, внешний по отношению к основной программе (например, аппаратное прерывание). – petitponey

ответ

1

Итак, я сделал комментарий, говоря, что volatile - плохой запах в многопоточных контекстах, и я поддерживаю это.

Это также плохой запах для управления вашими данными в обработчике сигналов. Использование блокировок также не работает в обработчиках сигналов, так как нет другого потока, чтобы разблокировать блокировку, удерживаемую основным потоком программы.

Я бы сказал, что вам нужно переосмыслить всю свою конструкцию и использовать два потока [один из которых может управляться обработчиком сигнала таймера и имеет высокий приоритет]. Дело в том, что манипулирование вашим итератором и данными, на которые указывает итератор, нужно будет обрабатывать атомарно, а просто отметить что-то volatile не решает, что - volatile просто означает, что компилятор должен «делать то, что говорит код» »- но это не значит, что ваши данные безопасны.

Смежные вопросы