我正在编写一个基于FFmpeg的媒体播放器,但我有一个设计问题。我的代码调用一个函数,使用SDL的SDL_AddTimer函数以不规则的间隔渲染视频帧。我的问题是,如果我想在一个视频结束(或播放停止)而另一个视频开始时执行垃圾收集,我如何确保队列中或执行过程中没有更多的计时器,以避免访问突然被释放的对象。
根据您的具体实现,有很多不同的方法来解决您的问题。很少有基本的想法可以是:
-
定义一个布尔值,指定玩家是否正在运行(true=正在运行,false=未运行)
-
在每次与播放器相关的调用之前,检查该变量,如果它为false(播放器已停止),则关闭函数(立即返回)
-
然后,调用
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文章中解释所有的种族条件回避策略如果您需要提高性能,您应该为代码精确定义并发问题,并选择正确的策略。