一个用于播放器的多线程安全生产消费fifo实现

开发播放器等数据量大的程序,需要多线程实现线程安全的缓冲区。一个线程读磁盘或网络数据,另外线程对数据进行解码或其他处理,缓存其实是一个数据传输通道,类似硬件里面的FIFO。程序需要防止线程的数据完整性,还要支持数据空和满的控制。
下面是我使用的一个具体程序,使用正常,至于原理大家看操作系统有关书籍吧。主要用到锁、信号量等。

//cond.h定义线程安全使用的信号和互锁。
  #include <pthread.h>
  #include <time.h>
class Cond
{
public:
  Cond();
  ~Cond();
  //上锁
  int Lock();
  //解锁
  int Unlock();
  int Wait();  //等待信号
  int TimedWait(int second);
  int Signal();  //通知
  int Broadcast();//广播通知
private:
  pthread_mutex_t m_mutex;
  pthread_cond_t m_cond;
#endif

};
//cond.cpp
#include "Cond.h"
Cond::Cond()
{
    pthread_mutex_init(&m_mutex, NULL);
    pthread_cond_init(&m_cond, NULL);
}

Cond::~Cond()
{
    pthread_mutex_destroy(&m_mutex);
    pthread_cond_destroy(&m_cond);
}
//加锁
int Cond::Lock()
{
    return pthread_mutex_lock(&m_mutex);
}
//解锁
int Cond::Unlock()
{
    return pthread_mutex_unlock(&m_mutex);
}
int Cond::Wait()
{
    int ret = pthread_cond_wait(&m_cond, &m_mutex);
    return ret;
}
int Cond::TimedWait(int second)
{
    struct timespec abstime;
    clock_gettime(CLOCK_REALTIME, &abstime);
    abstime.tv_sec += second;
    return pthread_cond_timedwait(&m_cond, &m_mutex, &abstime);
}
int Cond::Signal()
{
    int ret = pthread_cond_signal(&m_cond);
    return ret;
}
//唤醒所有睡眠线程
int Cond::Broadcast()
{
    return pthread_cond_broadcast(&m_cond);
}

下面是具体使用。

   Cond *mConditon_Audio;
   std::list<AVPacket> mAudioPacktList;  //音频压缩包
bool inputAudioQuene( AVPacket &pkt)   //读取压缩视频文件后得到的数据音频包
{    //复制音频数据包
    if (av_packet_ref(const_cast<AVPacket *>(&mAudioStream->attached_pic),&pkt)<0)
    {
        return false;
    }
    mConditon_Audio->Lock();
    while(mAudioPacktList.size()>MAX_AUDIO_SIZE)   //判断是否读取包是否满
       { mConditon_Audio->Wait();}
    mAudioPacktList.push_back(pkt);
    mConditon_Audio->Signal();
    mConditon_Audio->Unlock();
    return true;
}

void clearAudioQuene()
{
    mConditon_Audio->Lock();
    for (AVPacket pkt : mAudioPacktList)
    {
        av_packet_unref(&pkt);
    }
    mAudioPacktList.clear();
    mConditon_Audio->Unlock();
}

使用FIFO里面的packet
    mConditon_Audio->Lock();
        while(mAudioPacktList.size() <= 0)  //判断是否FIFO是否读空了
        {
             mConditon_Audio->Unlock();
          mConditon_Audio->Wait();          
         }
        AVPacket packet = mAudioPacktList.front();  //没有空我们可以读出
        mAudioPacktList.pop_front();
        mConditon_Audio->Unlock();
        mConditon_Audio->Signal();      //读出后可以有空间,FIFO又可以读入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值