2016-09-13 31 views
-1

实现一个限定的队列落实界缓冲区(读者中读写器,模块之间的非块,作家之中块)

阅读:
如果队列为空,等到它可以随着时间的推移返回一个值了
如果另一个线程从队列中读取,然后等到该线程完成
从队列中取出第一个元素,并将其返回
不要阻塞如果一个线程被写入队列

写:
如果队列已满,等到如果另一个线程写入队列中的一个值读取超时
,等到线程完成
在队列
不要阻塞,如果年底写的元素一个线程从队列

阅读我不知道如果我的实现是正确

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

发现在我的代码中的错误:)
看跌期权(和get()方法,它调用wait_for()并检查返回值。
如果超时,则返回false,否则它假定满足等待条件并且代码继续放入/获取数据。
如果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; 
    }