1

私はこのコードで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いつでもメッセージを受け取ることができます
  • last6 行目で受信メッセージの再処理を避けるためにイテレータを追加しました
  • 8 行目では、メッセージを出力した位置を保持し、最後のメッセージよりも新しいメッセージのみを出力したいと考えています。

    私の問題: 反復が終了し、新しいメッセージがキューに追加されると、 iterator の値lastが変更され、 iterator の値と同じになるrstartため、新しく到着したメッセージは 6 行目に出力されません。

last = rQueue.rbegin()キューのロックを解除した後に新しい要素を受け取ると、値が変更される理由がわかりません。

ありがとう。

4

1 に答える 1

1

イテレータを に設定すると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);
  }
}
于 2013-11-08T18:01:51.097 に答える