linux下c++實現簡單的生產者消費者隊列模式

引言

生產者消費者是一個經典的模式

利用生產者,消費者和緩衝區降低了生產者和消費者之間的的耦合度

便於對生產者和消費者的修改

下面記錄的是一個經典的單一生產者多消費者的模式

設計思路

以隊列做為緩衝區,實現產品的FIFO

生產者調用緩衝區的push函數,將產品加入緩衝區

消費者調用緩衝區的pop函數,將產品從緩衝區取出

因為生產者與消費者分屬於不同的線程,所以要設置鎖

類的聲明

 

class CacheQueue
{
    private:
        /**
         * @brief 緩衝隊列
         */
        queue<int>* _requests;

        /**
         * @brief 互斥鎖
         **/
        pthread_mutex_t _mutex;

        /**
         * @brief Queue not full conditional object
         **/
        pthread_cond_t _not_full_cond;

        /**
         * @brief Queue not empty conditional object
         **/
        pthread_cond_t _not_empty_cond;

        uint32_t _bufSize;

    public:

        ChacheQueue();

        void SetMaxLength(uint32_t bufSize);
        /**
          * @brief 向隊列添加產品
          * @param [in] req: 待添加的產品
          **/
        void Push(int req);

        /**
          * @brief 從隊列中取出一個產品
          * @param [return] : 從隊列中取出的產品
          **/
        int Pop(uint32_t timeout);

        /**
          * @brief 析構函數
          **/
        ~CacheQueue();
};

重要的函數是Push和Pop,生產者調用Push向緩衝區添加產品,消費者則調用Pop函數獲取產品

線程條件_not_full_cond表示隊列不滿,可以添加產品

線程條件_not_empty_cond表示隊列不空,可以獲取產品

Push函數

 

void CacheQueue::Push(int req)
{
	/**
	* 上鎖
	*/
    pthread_mutex_lock(&_mutex);

	/**
	* 如果隊列滿,等待信號
	*/
    while (_requests->size() == _bufSize)
    {
        pthread_cond_wait(&_not_full_cond, &_mutex);
    }
    _requests->push(req);

	/**
	* 發送非空信號
	*/
    pthread_cond_signal(&_not_empty_cond);

	/**
	* 解鎖
	*/
    pthread_mutex_unlock(&_mutex);
}

 

Pop函數

 

int CacheQueue::Pop(uint32_t timeout)
{
    int ret = 0;
    int req = NO_DATA;
	/**
	* 上鎖
	*/
    pthread_mutex_lock(&_mutex);
	/**
	* 若隊列空等待指定時間
	*/
    struct timeval now;
	struct timespec timepass;
	gettimeofday(&now, NULL);
	timepass.tv_sec = now.tv_sec + timeout;
	timepass.tv_nsec = 0;
    while (ret == 0 && _requests->empty())
    {
		ret = pthread_cond_timedwait(&_not_empty_cond, &_mutex, &timepass);
    }
	/**
	* 沒有數據,返回沒有數據標識
	*/
    if(ret!=0)
    {
        pthread_mutex_unlock(&_mutex);
        return req;
    }
	/**
	* 返回數據,發送隊列非滿信號
	*/
    req = _requests->front();
    _requests->pop();
    pthread_cond_signal(&_not_full_cond);
	/**
	* 解鎖
	*/
    pthread_mutex_unlock(&_mutex);
    return req;
}
时间: 2024-09-20 07:55:47

linux下c++實現簡單的生產者消費者隊列模式的相关文章

Linux下配置Apache httpd

httpd是Apache超文本传输协议(HTTP)服务器的主程序.它被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池对外提供服务.httpd支持基于 虚拟主机,以及基于HOST.IP.PORT实现虚拟主机,反向代理,负载均衡,路径别名,用户认证,basic,支持第三方模块等众多特性.本文主要描述了Linux下httpd(2.2版本)的相关基本配置. 1.配置文件概述 配置文件,主要分为3个部分: # grep "Section" /etc/httpd/conf/h

求幫忙,如何用POI同時從EXCEL內讀取圖片和內嵌EXCEL呢,兩個單獨都可實現!

问题描述 求好人幫忙,如何同時從EXCEL內讀取圖片和內嵌EXCEL呢,兩個單獨都可實現!代碼如下:importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjavassist.bytecode.Descriptor.Iterator;importorg.apache.poi.hslf.use

Csharp windowform bindingNavigator,bindingSource,DataGridView簡單分頁:首頁,上一頁,下一頁,末頁

/// <summary> /// 塗聚文 2011-10-24 (參考相關網絡資料) /// 締友計算機信息技術有限公司 ///C# Winform 簡單分頁: 首頁,上一頁,下一頁,末頁 /// </summary> public partial class FormDataGridViewPage : Form { /// <summary> /// 每页显示行数 /// </summary> int pageSize = 0; /// <sum

3層﹖﹖﹖﹖﹖﹖﹖﹖﹖﹖(簡單)

问题描述 寫一簡單的3層程式﹖可是為啥調用不了其中的東西﹖﹖﹖publicDataTableShowStu(){return(new...);}同時有曉得簡單分層的實例的么﹖要有視頻更好!!! 解决方案 解决方案二:publicDataTableShowStu(){return(new...);}具体是什么,出什么问题了?解决方案三:没有什么,类似的例子很多的解决方案四:楼主问题描述的清晰点~~解决方案五:正確的代碼應該如下﹕publicDataTableShowStu(){return(new

如何在FOXPRO中實現人民幣大寫的轉換

FOXPRO中人民幣大寫轉換的實現 作者:   CCBZZP        FOXPRO在實現報表的功能是很強大的, 特別在現實的應用中會經常用到人民幣 大小寫轉換的問題, 在此我簡單介紹一下, 希望和大家一起探討, 以便共同進步! 共同 發展! 假如 變量 MONEY 是我們要轉換的參數,我們在程序(*.PRG)中這樣寫:   PARA MONEYIF MONEY>999999999.99    RETURN ('<數值大于拾億! >')ENDIFIF ABS(MONEY)<1 

在DB2中如何實現Oracle的相關功能(三)

oracle 在DB2中如何實現Oracle的相關功能(三)作者﹕CCBZZP    在現實的應用中大家可能經常會遇到在DB2中如何實現Oracle的某些功能﹐在此我簡單地總結一下﹐實現某一功能可能會有很多種方法﹐在此就沒有全部列出﹐歡迎大家繼續﹐以便和大家共享﹐共同探討﹐共同近步﹗(以下主要以Oracle8I,9I和DB2 7.X為例).1.如何查有多少個數据庫實例的Oracle和DB2的寫法  Oracle 可以這樣實現﹕  SQL>SELECT * FROM V$INSTANCE;  DB

在DB2中如何實現Oracle的相關功能(一)

oracle 在DB2中如何實現Oracle的相關功能(一)作者﹕CCBZZP    在現實的應用中大家可能經常會遇到在DB2中如何實現Oracle的某些功能﹐在此我簡單地總結一下﹐實現某一功能可能會有很多種方法﹐在此就沒有全部列出﹐歡迎大家繼續﹐以便和大家共享﹐共同探討﹐共同近步﹗(以下主要以Oracle8I和DB2 7.X為例). 1.如何取一表前n筆記錄的Oracle和DB2的寫法  Oracle 可以這樣實現﹕   Select * from user.bsempms where row

在DB2中如何實現Oracle的相關功能(二)

oracle 在DB2中如何實現Oracle的相關功能(二)作者﹕CCBZZP    在現實的應用中大家可能經常會遇到在DB2中如何實現Oracle的某些功能﹐在此我簡單地總結一下﹐實現某一功能可能會有很多種方法﹐在此就沒有全部列出﹐歡迎大家繼續﹐以便和大家共享﹐共同探討﹐共同近步﹗(以下主要以Oracle8I,9I和DB2 7.X為例).1.如何查看數据庫的版本的Oracle和DB2的寫法  Oracle 可以這樣實現﹕  SQL> connect system/manager124@test

在DB2中如何實現Oracle的相關功能(四)

oracle  在DB2中如何實現Oracle的相關功能(四)作者﹕CCBZZP        在現實的應用中大家可能經常會遇到在DB2中如何實現Oracle的某些功能﹐在此我簡單地總結一下﹐實現某一功能可能會有很多種方法﹐在此就沒有全部列出﹐歡迎大家繼續﹐以便和大家共享﹐共同探討﹐共同近步﹗(以下主要以Oracle8I,9I和DB2 7.X為例).1.如何實現分頁顯示的Oracle和DB2的寫法  Oracle 可以這樣實現﹕  SQL>select rownum,* from BSEMPMS