SDL_Thread中的同步

SDL中带有几个子系统,其中有thread子系统。

前天想用c++重写一下ffplay.c,发现其中的回调函数在c++中不好用,还要继续学习。先练习了一下使用SDL_thread对队列进行操作。队列的同步问题是一个重点。

程序模拟对audio_queue和video_queue进行操作。

主进程发送包到audio_queue和video_queue,然后audio_thread和video_thread对audio_queue和video_queue分别进行处理。

为了防止在队列中积累的包数据太多,对于每个队列使用了初始值为max_queue_num的semaphore,每次投递一个包,对semaphore进行wait操作,每个thread取出一个包对semaphore进行post操作。保证了队列长队不超过10;

开始时由于对mutex的理解有误区,写的程序不稳定,修改后的终于成功了;

#include "simplayer.h"
#define MAX_QUEUE_SIZE 10
#include <list>
#include <windows.h>
using std::list;
FILE *trace;
list <int > audio_queue;
list <int > video_queue;
SDL_sem   *pAudioSem;
SDL_sem   *pVideoSem;

bool flag = true;
int AudioThread(void *arg)
{
 
 SDL_mutex *pInternalMutex= (SDL_mutex *)arg;
 
 fprintf(trace, "enter audio_queue thread /n");
 int i = 0;
 while(true)
 {
  int ret = SDL_LockMutex(pInternalMutex);
  int size = 0;
  if(ret == 0)
  {
   size = audio_queue.size();
   SDL_UnlockMutex(pInternalMutex);
  }
  else
  {
   continue;
  }
  if(size == 0)
  {
   fprintf(trace,"audio_queue size is zero/n");
   //break;
   SDL_Delay(10);
   continue;
  }
  ret = SDL_LockMutex(pInternalMutex);
  if(ret == 0)
  {
   i = audio_queue.front();
   audio_queue.pop_front();
   SDL_SemPost(pAudioSem);
   fprintf(trace,"in audio_queue get audio element is  %d/n",i);
   SDL_UnlockMutex(pInternalMutex);
   if(i == 10000)
   {
    break;
   }
  }
  else
  {
   fprintf(trace,"can't get lock in the audio_queue/n");
   continue;
  }
    
  
 }
 fprintf(trace,"leave thread audio_queue thread/n");
 return i;
}
int VideoThread(void *arg)
{
 SDL_mutex *pInternalMutex= (SDL_mutex *)arg;
 
 fprintf(trace, "enter thread video_queue thread /n");
 int i = 0;
 while(true)
 {
  int ret = SDL_LockMutex(pInternalMutex);
  int size = 0;
  if(ret == 0)
  {
   size = video_queue.size();
   SDL_UnlockMutex(pInternalMutex);
  }
  else
  {
   continue;
  }
  if(size == 0)
  {
   
   fprintf(trace, "video queue size is zero/n");
   //break;
   SDL_Delay(10);
   continue;
  }
  ret = SDL_LockMutex(pInternalMutex);
  if(ret == 0)
  {
   i = video_queue.front();
   video_queue.pop_front();
   SDL_SemPost(pVideoSem);
   fprintf(trace,"in video_queue get video element is  %d/n",i);
   SDL_UnlockMutex(pInternalMutex);
   if(i == 9999)
   {
    break;
   }
  }
  else
  {
   fprintf(trace,"can't get lock in the video_queue/n");
   continue;
  }
  
  
 }
 fprintf(trace,"leave thread video_queue /n");
 return i;
}
int main(int argc ,char **argv)
{
 SDL_Init(SDL_INIT_EVERYTHING);
 int audio_queue_cnt = 0;
 int video_queue_cnt = 0;
 int ret1= 0;
 int ret2= 0;
 
 int i = 0;
 trace = fopen("trace.txt","wt");
 SDL_mutex *pAudioMutex = NULL;
 SDL_mutex *pVideoMutex = NULL;
 pAudioMutex = SDL_CreateMutex();
 pVideoMutex = SDL_CreateMutex();
 pAudioSem = SDL_CreateSemaphore(MAX_QUEUE_SIZE);
 pVideoSem = SDL_CreateSemaphore(MAX_QUEUE_SIZE);
 SDL_Thread *audio_thread = SDL_CreateThread(AudioThread, pAudioMutex);
 SDL_Thread *video_thread = SDL_CreateThread(VideoThread,  pVideoMutex);
 while(flag)
 {
  
  i++;
  if(i%2 == 0)
  {
   //fprintf(trace, "before put an element to the audio_queue/n ");
   SDL_SemWait(pAudioSem);
   int ret = SDL_LockMutex(pAudioMutex);
   if(ret == 0)
   {
    fprintf(trace, "put an element %d to the audio_queue..../n",i);
    audio_queue.push_back(i);
    SDL_UnlockMutex(pAudioMutex);
   }
   else
   {
    fprintf(trace, "can't get audio_queue lock/n");
   }
   
   //fprintf(trace, "after put an element to the audio_queue/n ");
  }
  else
  {
   //fprintf(trace, "before put an element to the video_queue/n ");
   SDL_SemWait(pVideoSem);
   int ret = SDL_LockMutex(pVideoMutex);
   if(ret == 0)
   {
    fprintf(trace, "put an element %d to the video_queue.../n",i);
    video_queue.push_back(i);
    SDL_UnlockMutex(pVideoMutex);

   }
   else
   {
    fprintf(trace, "can't get video_queue lock/n");
   }
      //fprintf(trace, "after put an element to the video_queue/n ");
  }
  
  if(audio_queue.size() >MAX_QUEUE_SIZE || video_queue.size() > MAX_QUEUE_SIZE )
  {
   //Sleep(1000);
  }
  if(i == 10000)
  {
   flag = false;
  }
  
 }
 
 SDL_WaitThread(audio_thread, &ret1);
 fprintf(trace,"audio thread exit with value  %d /n", ret1);
 SDL_WaitThread(video_thread, &ret2);
 fprintf(trace, "video thread exit with value %d /n", ret2);
 SDL_DestroySemaphore(pAudioSem);
 SDL_DestroySemaphore(pVideoSem);
 system("pause");
 return 0;
 
}

simPlay.h 中包含有常用的sdl.h

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值