线程安全的环形缓冲区实现
来源:http://blog.csdn.net/lezhiyong
应用背景:线程1将每次数量不一的音频采样点(PCM音频数据)写入环形缓冲区,线程2每次取固定数量采样点送音频编码器,线程1线程2在平均时间内的读写数据量相等。(倒入桶中的水量有时大有时小,但每次取一瓢喝:)
该环形缓冲区借鉴CoolPlayer音频播放器中的环形缓冲区代码实现,在读写操作函数中加了锁,允许多线程同时操作。CPs_CircleBuffer基于内存段的读写,比用模板实现的环形缓冲队列适用的数据类型更广些, CPs_CircleBuffer修改成C++中基于对象的实现,加上详细注释,m_csCircleBuffer锁变量为自用的lock类型(将CRITICAL_SECTION封装起来),调用lock()加锁,调用unlock()解锁。使用效果良好,分享出来。
CPs_CircleBuffer环形缓冲还不具备当待写数据量超出空余缓冲时自动分配内存的功能,这个将在后续进行优化。
CPs_CircleBuffer使用步骤:
class CPs_CircleBuffer{public: CPs_CircleBuffer(const unsigned int iBufferSize); ~CPs_CircleBuffer();public: // Public functions void Uninitialise(); void Write(const void* pSourceBuffer, const unsigned int iNumBytes); bool Read(void* pDestBuffer, const size_t iBytesToRead, size_t* pbBytesRead); void Flush(); unsigned int GetUsedSize(); unsigned int GetFreeSize(); void SetComplete(); bool IsComplete();private: unsigned char*m_pBuffer; unsigned intm_iBufferSize; unsigned intm_iReadCursor; unsigned intm_iWriteCursor; HANDLEm_evtDataAvailable; Vlockm_csCircleBuffer; boolm_bComplete; };CPs_CircleBuffer修改为类的实现:#ifdef WIN32#include <windows.h>#define V_MUTEXCRITICAL_SECTION //利用临界区实现的锁变量#define V_MUTEX_INIT(m)InitializeCriticalSection(m)#define V_MUTEX_LOCK(m)EnterCriticalSection(m)#define V_MUTEX_UNLOCK(m)LeaveCriticalSection(m)#define V_MUTEX_DESTORY(m)DeleteCriticalSection(m)#else#define V_MUTEXpthread_mutex_t#define V_MUTEX_INIT(m)pthread_mutex_init(m,NULL)#define V_MUTEX_LOCK(m)pthread_mutex_Lock(m)#define V_MUTEX_UNLOCK(m)pthread_mutex_unLock(m)#define V_MUTEX_DESTORY(m)pthread_mutex_destroy(m)#endifclass Vlock{public:Vlock(void){V_MUTEX_INIT(&m_Lock);}~Vlock(void){V_MUTEX_DESTORY(&m_Lock);}public:void Lock(){V_MUTEX_LOCK(&m_Lock);}void UnLock(){V_MUTEX_UNLOCK(&m_Lock);}private:V_MUTEX m_Lock;};- 2楼han_yankun2009昨天 14:56
- 学习了
- 1楼leihengxin昨天 07:57
- 嗯。