2013-03-10 109 views
2

我有一個快速生產者插入隊列中的數據和慢速消費者消費數據的用例。我面臨的問題是隨着時間的推移隊列大小不斷增加。我有一個類實現,其中一個std ::隊列被互斥鎖和條件變量保護,用於併發讀寫。快速生產者和緩慢消費者

這怎麼適應這種情況,生產者在達到MAX_THRESHOLD之後,直到停止插入數據到隊列中,並且消費者已經消耗了生產者將數據插入隊列的一些數據信號。

有人可以提供一個示例實現嗎?

此外,在不改變類實現的情況下,是否可以通過在生產者和消費者中添加另一層同步來解決此問題?

+0

顯示你的代碼。 – 2013-03-10 20:55:32

+0

另請參閱http://programmers.stackexchange.com/q/244826/24257 – Pacerier 2015-09-14 11:33:14

回答

1

代碼片段:

#include <queue> 
#include <pthread.h> 

template <class T, size_t UpperLimit> 
class BoundedQueue { 
    std::queue<T> q_; 
    pthread_mutex_t mtx_; 
    pthread_cond_t cv_not_empry_; 
    pthread_cond_t cv_not_full_; 

    // lock/unlock helper 
    struct auto_locker { 
    auto_locker(pthread_mutex_t* pm) : pm_(pm) 
     { pthread_mutex_lock(pm_); } 
    ~auto_locker() 
     { pthread_mutex_unlock(pm_);} 
    pthread_mutex_t *pm_; 
    }; 

public: 
    BoundedQueue() { /* initialize member... */ } 
    ~BoundedQueue() { /* uninitialize member...*/ } 
    // for Producer 
    void push(T x) { 
    auto_locker lk(&mtx_); 
    while (UpperLimit <= q_.size()) { 
     pthread_cond_wait(&cv_not_full_, &mtx_); 
    } 
    q_.push(x); 
    pthread_cond_broadcast(&cv_not_empry_); 
    return ret; 
    } 
    // for Consumer 
    T pop() { 
    auto_locker lk(&mtx_); 
    while (q_.empty()) { 
     pthread_cond_wait(&cv_not_empry_, &mtx_); 
    } 
    T ret = q_.front(); 
    q_.pop(); 
    pthread_cond_broadcast(&cv_not_full_); 
    return ret; 
    } 
} 
4

或者:

a)使用一個有界隊列類塊如果隊列大小達到MAX_THRESHOLD生產者。這意味着更改您可能不需要的隊列類。

b)使用「池隊列」 - 另一個無限制的阻塞隊列,在啓動時填充MAX_THRESHOLD對象。生產者從池中獲取它的對象,加載它們,排隊到生產者。生產者從消費者那裏獲取對象,「消費」它們並將它們返回到池中。這種有點使用指針或可能引用,你可能不希望。

c)使用以MAX_THRESHOLD計數初始化的信號量以類似於(b)的方式表示消息標記 - 生產者在排隊之前必須獲取單元,消費者在完成消息時發佈單元目的。

我傾向於使用(b)。與並行線程 「界隊列」 的

+0

您是否在介紹第二種方法 - 「泳池隊列」? – Pacerier 2015-09-14 11:28:24