SDL_AddTimer 和线程,清除定时器队列

5
我正在基于FFmpeg编写媒体播放器,但遇到了设计问题。我的代码使用SDL的SDL_AddTimer函数在不规则的时间间隔内调用渲染视频帧的函数。我的问题是,如果我想在一个视频结束(或播放停止)并开始另一个视频时执行垃圾回收,如何确保没有更多的计时器在队列中或正在执行中,以避免访问突然被释放的对象。

关于“执行中”的部分,您可以使用例如互斥锁进行锁定。不确定为什么在此处具有排队但非活动计时器很重要。 - keltar
1个回答

3
基于您的特定实现,有很多不同的方法可以解决您的问题。一些基本的想法可能包括:
  1. 定义一个布尔值,指定播放器是否正在运行(true = 正在运行,false = 停止)

  2. 在与播放器相关的每个调用之前,检查该变量是否为假(播放器已停止),如果是,关闭函数(立即返回)

  3. 然后,您调用removeTimer并将变量设置为false以关闭播放器。

然而,因为addTimer是创建线程的函数,所以有时会出现竞争条件(您称之为“执行中间”)。这是使用线程时的主要问题之一。
您需要使用诸如互斥锁、信号量等工具来查找和修复它们。选择这些工具非常依赖于您想要实现避免这些竞争条件的策略。
因此,没有通用的解决方案。如果性能不是问题,您可以使用这种简单的“一锁”解决方案。它是“临界区”策略的基本实现。它可以防止某些代码片段(关闭播放器和运行关键声音相关的调用)同时运行。
#include <pthread.h>
#include <stdbool.h>

pthread_mutex_t mutex; 
bool isRunning; 
int timerID; 

void timerCallback(){
    // do some computations 

    pthread_mutex_lock(&mutex); 
    // that critical section, defined here will never 
    // (thank to the mutex) occur at the same time at 
    // the critical section in the close method 

    if(isRunning){
         // do critical calls
    }
    else{
         // do nothing
    }
    pthread_mutex_unlock(&mutex); 

    // do some other computations
}

void init(){
    pthread_mutex_init(&mutex, NULL); 
    isRunning = true; 
    startTimers(); 
}

void close(){
    pthread_mutex_lock(&mutex); 

    // that critical section, defined here will never 
    // (thank to the mutex) occur at the same time at 
    // the critical section in the timerCallback method 
    SDL_RemoveTimer(timerID); 
    isRunning = false; 
    pthread_mutex_unlock(&mutex); 

    pthread_mutex_destroy(&mutex); 
}

当然,我不能在简单的stackoverflow帖子中解释所有避免竞态条件的策略。如果你需要提高性能,你应该明确你的代码并发问题,并选择正确的策略。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接