У меня странная проблема в C ++ с этим кодом:
mutex_type list_mutex;
typedef list<char*> RQueue;
RQueue rQueue;
RQueue::reverse_iterator rstart, rend, last;
1 while(true) {
2 LockMutex(list_mutex);
3 rstart = rQueue.rbegin();
4 rend = rQueue.rend();
5 while( (rstart != rend) && (rstart != last) ) {
6 print *rstart;
7 }
8 last = rQueue.rbegin();
9 UnlockMutex(list_mutex);
10 }
rQueue
это очередь, в которой я повторяю в обратном порядкеrQueue
можете получать сообщения в любое времяlast
чтобыВ строке 8 я сохраняю позицию, откуда я напечатал сообщения, и я хочу
распечатывать только те сообщения, которые новее, чем последнее сообщение.
Моя проблема: когда итерация закончена и новые сообщения добавлены в
очередь, значение итератора last
меняется, становясь таким же
как значение итератора rstart
следовательно, новый прибыл
сообщения не печатаются в строке 6.
Я не знаю почему last = rQueue.rbegin()
изменяет его значение при получении новых элементов после разблокировки очереди.
Благодарю.
Если вы установите итератор в rbegin()
всегда будет указывать на последний элемент списка. Если вы добавите еще один элемент сзади, итератор будет по-прежнему указывать на последний элемент (который теперь является новым). Он не изменится, он просто будет указывать на конец.
Я сделал этот тест:
list<const char *> my_list;
my_list.push_back("msg 1");
list<const char*>::reverse_iterator it = my_list.rbegin();
cout << "Iterator is " << *it << endl;
my_list.push_back("msg 2");
my_list.push_back("msg 3");
my_list.push_back("msg 4");
cout << "Iterator is " << *it << endl;
Эта программа дает вывод:
Iterator is msg 1
Iterator is msg 4
У меня есть другое решение, которое вы могли бы использовать, которое не использует обратный итератор. Вместо этого addMessage()
обновления read_pos
к новейшему сообщению. Если read_pos
не указывает на конец, он также не изменяется. Это позволяет printMessage()
распечатать все сообщения, которые были добавлены с момента последнего запуска.
Обратите внимание, что я проверял это только без блокировки.
mutex_type list_mutex;
typedef list<const char*> RQueue;
RQueue rQueue;
RQueue::iterator read_pos;
void addMessage(const char *message) {
LockMutex(list_mutex);
rQueue.push_back(message);
if (rQueue.size() == 1) {
read_pos = rQueue.begin();
}
else if (read_pos == rQueue.end()) {
read_pos--;
}
UnlockMutex(list_mutex);
}
void printMessage() {
RQueue::iterator prev_pos;
while (true) {
LockMutex(list_mutex);
if (rQueue.size() == 0) {
UnlockMutex(list_mutex);
continue;
}
RQueue::iterator end = rQueue.end();
while (read_pos != end) {
cout << *read_pos << endl;
read_pos++;
}
UnlockMutex(list_mutex);
}
}
Других решений пока нет …