校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > linux中編寫自己的并發隊列類(Queue 并發阻塞隊列)

linux中編寫自己的并發隊列類(Queue 并發阻塞隊列)

熱門標簽:河南信譽好的不封卡電話外呼系統 如果做線上地圖標注 地圖標注員都是年輕人 華鋒e路航港口地圖標注 百度地圖標注錯了有責任嗎 揭陽智能電話機器人推薦 江蘇云電銷機器人公司 客服外呼系統怎么樣 打電話機器人接我是他的秘書

設計并發隊列

復制代碼 代碼如下:

#include pthread.h>
#include list>
using namespace std;

template typename T>
class Queue
{
public:
    Queue( )
    {
        pthread_mutex_init(_lock, NULL);
    }
    ~Queue( )
    {
        pthread_mutex_destroy(_lock);
    }
    void push(const T data);
    T pop( );
private:
    listT> _list;
    pthread_mutex_t _lock;
};

template typename T>
void QueueT>::push(const T value )
{
    pthread_mutex_lock(_lock);
    _list.push_back(value);
    pthread_mutex_unlock(_lock);
}

template typename T>
T QueueT>::pop( )
{
    if (_list.empty( ))
    {
        throw "element not found";
    }
    pthread_mutex_lock(_lock);
    T _temp = _list.front( );
    _list.pop_front( );
    pthread_mutex_unlock(_lock);
    return _temp;
}

上述代碼是有效的。但是,請考慮這樣的情況:您有一個很長的隊列(可能包含超過 100,000 個元素),而且在代碼執行期間的某個時候,從隊列中讀取數據的線程遠遠多于添加數據的線程。因為添加和取出數據操作使用相同的互斥鎖,所以讀取數據的速度會影響寫數據的線程訪問鎖。那么,使用兩個鎖怎么樣?一個鎖用于讀取操作,另一個用于寫操作。給出修改后的 Queue 類。

復制代碼 代碼如下:

template typename T>
class Queue
{
public:
    Queue( )
    {
        pthread_mutex_init(_rlock, NULL);
        pthread_mutex_init(_wlock, NULL);
    }
    ~Queue( )
    {
        pthread_mutex_destroy(_rlock);
        pthread_mutex_destroy(_wlock);
    }
    void push(const T data);
    T pop( );
private:
    listT> _list;
    pthread_mutex_t _rlock, _wlock;
};


template typename T>
void QueueT>::push(const T value )
{
    pthread_mutex_lock(_wlock);
    _list.push_back(value);
    pthread_mutex_unlock(_wlock);
}

template typename T>
T QueueT>::pop( )
{
    if (_list.empty( ))
    {
        throw "element not found";
    }
    pthread_mutex_lock(_rlock);
    T _temp = _list.front( );
    _list.pop_front( );
    pthread_mutex_unlock(_rlock);
    return _temp;
}

設計并發阻塞隊列

目前,如果讀線程試圖從沒有數據的隊列讀取數據,僅僅會拋出異常并繼續執行。但是,這種做法不總是我們想要的,讀線程很可能希望等待(即阻塞自身),直到有數據可用時為止。這種隊列稱為阻塞的隊列。如何讓讀線程在發現隊列是空的之后等待?一種做法是定期輪詢隊列。但是,因為這種做法不保證隊列中有數據可用,它可能會導致浪費大量 CPU 周期。推薦的方法是使用條件變量,即 pthread_cond_t 類型的變量。

復制代碼 代碼如下:

template typename T>
class BlockingQueue
{
public:
    BlockingQueue ( )
    {
        pthread_mutexattr_init(_attr);
        // set lock recursive
        pthread_mutexattr_settype(_attr,PTHREAD_MUTEX_RECURSIVE_NP);
        pthread_mutex_init(_lock,_attr);
        pthread_cond_init(_cond, NULL);
    }
    ~BlockingQueue ( )
    {
        pthread_mutex_destroy(_lock);
        pthread_cond_destroy(_cond);
    }
    void push(const T data);
    bool push(const T data, const int seconds); //time-out push
    T pop( );
    T pop(const int seconds); // time-out pop

private:
    listT> _list;
    pthread_mutex_t _lock;
    pthread_mutexattr_t _attr;
    pthread_cond_t _cond;
};

template typename T>
T BlockingQueueT>::pop( )
{
    pthread_mutex_lock(_lock);
    while (_list.empty( ))
    {
        pthread_cond_wait(_cond, _lock) ;
    }
    T _temp = _list.front( );
    _list.pop_front( );
    pthread_mutex_unlock(_lock);
    return _temp;
}

template typename T>
void BlockingQueue T>::push(const T value )
{
    pthread_mutex_lock(_lock);
    const bool was_empty = _list.empty( );
    _list.push_back(value);
    pthread_mutex_unlock(_lock);
    if (was_empty)
        pthread_cond_broadcast(_cond);
}

并發阻塞隊列設計有兩個要注意的方面:

1.可以不使用 pthread_cond_broadcast,而是使用 pthread_cond_signal。但是,pthread_cond_signal 會釋放至少一個等待條件變量的線程,這個線程不一定是等待時間最長的讀線程。盡管使用 pthread_cond_signal 不會損害阻塞隊列的功能,但是這可能會導致某些讀線程的等待時間過長。

2.可能會出現虛假的線程喚醒。因此,在喚醒讀線程之后,要確認列表非空,然后再繼續處理。強烈建議使用基于 while 循環的 pop()。

設計有超時限制的并發阻塞隊列

在許多系統中,如果無法在特定的時間段內處理新數據,就根本不處理數據了。例如,新聞頻道的自動收報機顯示來自金融交易所的實時股票行情,它每 n 秒收到一次新數據。如果在 n 秒內無法處理以前的一些數據,就應該丟棄這些數據并顯示最新的信息。根據這個概念,我們來看看如何給并發隊列的添加和取出操作增加超時限制。這意味著,如果系統無法在指定的時間限制內執行添加和取出操作,就應該根本不執行操作。

復制代碼 代碼如下:

template typename T>
bool BlockingQueue T>::push(const T data, const int seconds)
{
    struct timespec ts1, ts2;
    const bool was_empty = _list.empty( );
    clock_gettime(CLOCK_REALTIME, ts1);
    pthread_mutex_lock(_lock);
    clock_gettime(CLOCK_REALTIME, ts2);
    if ((ts2.tv_sec – ts1.tv_sec) seconds)
    {
        was_empty = _list.empty( );
        _list.push_back(value);
    }
    pthread_mutex_unlock(_lock);
    if (was_empty)
        pthread_cond_broadcast(_cond);
}

template typename T>
T BlockingQueue T>::pop(const int seconds)
{
    struct timespec ts1, ts2;
    clock_gettime(CLOCK_REALTIME, ts1);
    pthread_mutex_lock(_lock);
    clock_gettime(CLOCK_REALTIME, ts2);

    // First Check: if time out when get the _lock
    if ((ts1.tv_sec – ts2.tv_sec) seconds)
    {
        ts2.tv_sec += seconds; // specify wake up time
        while(_list.empty( ) (result == 0))
        {
            result = pthread_cond_timedwait(_cond, _lock, ts2) ;
        }
        if (result == 0) // Second Check: if time out when timedwait 
        {
            T _temp = _list.front( );
            _list.pop_front( );
            pthread_mutex_unlock(_lock);
            return _temp;
        }
    }
    pthread_mutex_unlock(lock);
    throw "timeout happened";
}

設計有大小限制的并發阻塞隊列

最后,討論有大小限制的并發阻塞隊列。這種隊列與并發阻塞隊列相似,但是對隊列的大小有限制。在許多內存有限的嵌入式系統中,確實需要有大小限制的隊列。
對于阻塞隊列,只有讀線程需要在隊列中沒有數據時等待。對于有大小限制的阻塞隊列,如果隊列滿了,寫線程也需要等待。

復制代碼 代碼如下:

template typename T>
class BoundedBlockingQueue
{
public:
    BoundedBlockingQueue (int size) : maxSize(size)
    {
        pthread_mutex_init(_lock, NULL);
        pthread_cond_init(_rcond, NULL);
        pthread_cond_init(_wcond, NULL);
        _array.reserve(maxSize);
    }
    ~BoundedBlockingQueue ( )
    {
        pthread_mutex_destroy(_lock);
        pthread_cond_destroy(_rcond);
        pthread_cond_destroy(_wcond);
    }
    void push(const T data);
    T pop( );
private:
    vectorT> _array; // or T* _array if you so prefer
    int maxSize;
    pthread_mutex_t _lock;
    pthread_cond_t _rcond, _wcond;
};

template typename T>
void BoundedBlockingQueue T>::push(const T value )
{
    pthread_mutex_lock(_lock);
    const bool was_empty = _array.empty( );
    while (_array.size( ) == maxSize)
    {
        pthread_cond_wait(_wcond, _lock);
    }
    _array.push_back(value);
    pthread_mutex_unlock(_lock);
    if (was_empty)
        pthread_cond_broadcast(_rcond);
}

template typename T>
T BoundedBlockingQueueT>::pop( )
{
    pthread_mutex_lock(_lock);
    const bool was_full = (_array.size( ) == maxSize);
    while(_array.empty( ))
    {
        pthread_cond_wait(_rcond, _lock) ;
    }
    T _temp = _array.front( );
    _array.erase( _array.begin( ));
    pthread_mutex_unlock(_lock);
    if (was_full)
        pthread_cond_broadcast(_wcond);
    return _temp;
}

要注意的第一點是,這個阻塞隊列有兩個條件變量而不是一個。如果隊列滿了,寫線程等待 _wcond 條件變量;讀線程在從隊列中取出數據之后需要通知所有線程。同樣,如果隊列是空的,讀線程等待 _rcond 變量,寫線程在把數據插入隊列中之后向所有線程發送廣播消息。如果在發送廣播通知時沒有線程在等待 _wcond 或 _rcond,會發生什么?什么也不會發生;系統會忽略這些消息。還要注意,兩個條件變量使用相同的互斥鎖。

 

您可能感興趣的文章:
  • linux中高并發socket最大連接數的優化詳解
  • Linux netstat命令查看并發連接數的方法
  • Linux下高并發socket最大連接數所受的各種限制(詳解)
  • linux并發連接50萬的配置方法
  • 淺談Linux環境下并發編程中C語言fork()函數的使用
  • Linux下apache如何限制并發連接和下載速度
  • Linux并發執行很簡單,這么做就對了

標簽:許昌 赤峰 邵陽 巴彥淖爾 淘寶邀評 婁底 金昌 馬鞍山

巨人網絡通訊聲明:本文標題《linux中編寫自己的并發隊列類(Queue 并發阻塞隊列)》,本文關鍵詞  linux,中,編寫,自己的,并發,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《linux中編寫自己的并發隊列類(Queue 并發阻塞隊列)》相關的同類信息!
  • 本頁收集關于linux中編寫自己的并發隊列類(Queue 并發阻塞隊列)的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    久久在线免费观看| 91蜜桃免费观看视频| 欧美一区二区在线免费观看| 天堂av在线一区| 69久久夜色精品国产69蝌蚪网| 国产精品高潮呻吟| 成人国产精品免费观看视频| 精品美女被调教视频大全网站| 日韩精品一区在线| 免费高清成人在线| 亚洲精品在线观看视频| 国产福利一区在线观看| 国产精品视频在线看| 91浏览器打开| 日韩专区欧美专区| 欧美精品一区二区三| 国产精品18久久久| 亚洲综合一二区| 欧美videos中文字幕| 粉嫩久久99精品久久久久久夜| 欧美自拍偷拍一区| 午夜精品久久一牛影视| 精品国产1区二区| 成人教育av在线| 亚洲成人动漫在线观看| 精品欧美久久久| 99r精品视频| 麻豆精品一区二区综合av| 国产欧美一区二区在线| 欧洲一区二区三区在线| 精品在线播放午夜| 一区二区三区.www| 久久综合色播五月| 欧美亚洲国产一区在线观看网站| 国产精品美女久久久久久2018| 午夜视频一区在线观看| 日韩一区二区免费在线电影| 高潮精品一区videoshd| 天天综合日日夜夜精品| 国产精品久久久久久久久图文区| 加勒比av一区二区| 夜夜嗨av一区二区三区网页 | 成人综合婷婷国产精品久久| 久久久久97国产精华液好用吗| 麻豆91精品视频| 亚洲欧美日韩一区| 久久精品亚洲国产奇米99| 欧美日韩电影在线播放| www.亚洲免费av| 韩国v欧美v日本v亚洲v| 视频一区二区三区在线| 成人欧美一区二区三区视频网页 | 亚洲综合色在线| 精品久久久影院| 欧美日韩精品福利| 91麻豆123| 成人短视频下载| 青青草国产精品97视觉盛宴 | 91精品国产色综合久久ai换脸| 夜夜精品浪潮av一区二区三区| 成人看片黄a免费看在线| 午夜激情久久久| 亚洲美女区一区| 国产精品三级在线观看| 精品国产免费久久| 欧美一区二区三区免费大片| 欧美主播一区二区三区美女| www.激情成人| 风间由美一区二区av101| 乱中年女人伦av一区二区| 午夜精品视频在线观看| 亚洲综合男人的天堂| 最好看的中文字幕久久| 欧美国产成人精品| www国产精品av| 久久久影视传媒| 久久一留热品黄| 久久影音资源网| 久久网站热最新地址| 久久视频一区二区| 久久久99久久| 国产精品女同一区二区三区| 日本一区二区三区高清不卡| 久久久综合视频| 国产午夜精品一区二区| 国产精品拍天天在线| 国产精品美女久久久久aⅴ国产馆| 在线观看国产一区二区| 色中色一区二区| 色噜噜久久综合| 色综合久久久网| 欧美日韩二区三区| 日韩一区二区麻豆国产| 精品国产一区二区三区av性色| av一区二区三区四区| 成人的网站免费观看| 99国产精品99久久久久久| 在线日韩一区二区| 欧美日韩在线不卡| 精品少妇一区二区三区视频免付费 | 精品福利av导航| 国产网红主播福利一区二区| 欧美韩国日本综合| 亚洲美女精品一区| 麻豆视频一区二区| 白白色 亚洲乱淫| 日本韩国一区二区| 日韩视频一区二区在线观看| 久久久久久久久久久久久久久99| 欧美日本韩国一区| 久久综合资源网| 亚洲欧美日韩中文字幕一区二区三区| 欧美电影免费观看高清完整版在线观看| 风间由美一区二区三区在线观看 | 成人激情综合网站| 在线看不卡av| 宅男噜噜噜66一区二区66| 国产亚洲精品免费| 亚洲女子a中天字幕| 日韩成人免费看| 国产suv精品一区二区6| 欧美中文字幕一区二区三区 | 午夜久久久久久久久| 国产真实乱子伦精品视频| 成人h动漫精品一区二区| 欧美一区日本一区韩国一区| 中文一区二区在线观看| 亚洲va欧美va人人爽午夜| 国产精品1区二区.| 欧美精品一二三四| 日韩理论片在线| 久久成人久久爱| 91成人免费在线| 欧美激情艳妇裸体舞| 六月婷婷色综合| 在线观看日韩av先锋影音电影院| 色屁屁一区二区| 欧美国产精品一区| 久久99热国产| 91麻豆精品国产91久久久资源速度| 欧美伊人久久久久久久久影院| 日本韩国一区二区| 国产日韩欧美a| 麻豆国产精品视频| 欧美猛男超大videosgay| 国产精品毛片无遮挡高清| 日本三级亚洲精品| 欧美视频一区二区三区四区| 中文字幕av免费专区久久| 看片网站欧美日韩| 精品视频资源站| 亚洲日本护士毛茸茸| 国产尤物一区二区在线| 欧美一级日韩一级| 天天影视网天天综合色在线播放| 亚洲成人av福利| 91在线视频网址| 国产亚洲精品中文字幕| 久久精品72免费观看| 69堂成人精品免费视频| 亚洲高清免费观看高清完整版在线观看 | 国产精品一区二区久久不卡| 欧美一区二区三区喷汁尤物| 午夜精品久久久久久久99水蜜桃| 一区二区欧美视频| 色悠久久久久综合欧美99| 亚洲欧美日韩国产综合在线| 白白色 亚洲乱淫| 欧美国产丝袜视频| 高清不卡在线观看av| 国产精品久久久久四虎| 国产成人高清在线| 国产欧美综合在线观看第十页| 亚洲综合清纯丝袜自拍| 日本高清不卡一区| 一区二区三区视频在线看| 色综合久久久久综合体桃花网| 欧美网站大全在线观看| 亚洲自拍偷拍麻豆| 欧美亚一区二区| 日韩电影在线一区二区| 6080国产精品一区二区| 蜜桃av噜噜一区| 欧美成人欧美edvon| 国产乱人伦偷精品视频免下载| 日本道色综合久久| 一区二区在线观看视频| 精品1区2区3区| 久久精品国产77777蜜臀| 久久久久久久久99精品| www.视频一区| 图片区小说区国产精品视频| 欧美撒尿777hd撒尿| 老司机免费视频一区二区三区| 99re6这里只有精品视频在线观看| 精品少妇一区二区| 国产成人激情av| 亚洲曰韩产成在线| 精品少妇一区二区| 91在线精品一区二区|