2016-09-13 4 views
-1

を実装:キューが空であれば、それはアウト時間の経過とともに値を返すことができるまで、待って
を:スレッドがキュー
有界キュー</p> <p>読む実装有界バッファ(リーダライタとの間の非ブロック、読者の間でブロック、作家の間でブロック)

書き込みへの書き込みされている場合
別のスレッドがキューから読んでいる場合、そのスレッドは
に行われるまで待つキューから最初の要素を削除し、返すことが
はふさがないでくださいキューがいっぱいの場合 は、一つの値が別のスレッドがキューに書き込みをされている場合は、そのスレッドまで待つタイムアウト
で読まれるまで待つが
に行われた場合にふさがないでくださいキュー
の末尾に要素を書きますスレッドは、私は私の実装は私のコードにバグが見つかりました

using namespace std; 

template <typename T, int N> 
class BoundedBuffer { 
private: 
    std::array<T, N> buffer; 
    int read_pos; 
    int write_pos; 

    std::mutex reader_mutex; //mutex for between readers 
    std::mutex writer_mutex; //mutex for between writers 

    std::mutex shared_mutex; 
    std::condition_variable reader_queue; 
    std::condition_variable writer_queue; 
    int timeout; //timeout in millisecond 


public: 
    BoundedBuffer(const BoundedBuffer&) = delete; 
    BoundedBuffer& operator=(const BoundedBuffer&) = delete; 

    BoundedBuffer(int t) : 
     read_pos(0), 
     write_pos(0), 
     timeout(t) { 
    } 

    inline bool empty() { 
     return read_pos == write_pos; 
    } 

    inline bool full() { 
     return write_pos >= read_pos + N; 
    } 

    bool put(const T& data) { 
     unique_lock<mutex> writer_lock(writer_mutex); 

     { 
      unique_lock<mutex> shared_lock(shared_mutex); 
      if (full()) { //buffer full 
       if (writer_queue.wait_for(shared_lock, std::chrono::milliseconds(timeout)) == 
        std::cv_status::timeout) 
        return false; 
      } 
     } 

     buffer[write_pos%N] = data; 
     write_pos++; 
     reader_queue.notify_one(); 
     return true; 
    } 

    pair<T, bool> get() { 
     unique_lock<mutex> reader_lock(reader_mutex); 

     { 
      unique_lock<mutex> shared_lock(shared_mutex); 
      if (empty()) { //buffer empty 
       if (reader_queue.wait_for(shared_lock, std::chrono::milliseconds(timeout)) == 
        std::cv_status::timeout) { 
        T t; 
        return make_pair(t, false); 
       } 
      } 
     } 

     pair<T, bool> result = make_pair(buffer[read_pos%N], true); 
     read_pos++; 
     writer_queue.notify_one(); 
     return result; 
    } 
}; 

答えて

0

正しいかどうかはわからないキューから

を読んでいる:プットで
を()と()メソッドを取得し、それが呼び出されますwait_for()を呼び出し、戻り値をチェックします。
タイムアウトの場合は、falseを返します。それ以外の場合は、待機条件が満たされているとみなされ、コードはデータのput/getを継続します。 wait_forは()ので、スプリアスウェイクアップの戻って、一度に条件が満たされない場合
:プットのため
がフルでない()とのための空ではない()を取得、
それは、既存のデータを上書きしたり、間違った読みますデータ。

修正点は、wait_for()で述部を使用することです。それは偽の起床を無視します。

bool put(const T& data) { 
      unique_lock<mutex> writer_lock(writer_mutex); 

      { 
        unique_lock<mutex> shared_lock(shared_mutex); 
        if (full()) { //buffer full 
          if (writer_queue.wait_for(shared_lock, std::chrono::milliseconds(timeout), 
            [this]() { return !full(); }) == false) { 
            return false; 
          } 
        } 
      } 

      buffer[write_pos%N] = data; 
      write_pos++; 
      reader_queue.notify_one(); 
      return true; 
    } 


    pair<T, bool> get(int i) { 
      unique_lock<mutex> reader_lock(reader_mutex); 
      cout << "i : " << i << endl; 

      { 
        unique_lock<mutex> shared_lock(shared_mutex); 
        if (empty()) { //buffer empty 
          if (reader_queue.wait_for(shared_lock, std::chrono::milliseconds(timeout), 
            [this]() { return !empty(); })==false) { 
            T t; 
            return make_pair(t, false); 
          } 
        } 
      } 

      pair<T, bool> result = make_pair(buffer[read_pos%N], true); 
      read_pos++; 
      writer_queue.notify_one(); 
      return result; 
    } 
関連する問題