我正在编写基于FFmpeg的媒体播放器,我遇到了设计问题。我的代码调用一个函数,使用SDL的SDL_AddTimer函数以不规则的间隔渲染视频帧。我的问题是,如果我想在一个视频结束(或播放停止)和另一个视频开始时执行垃圾收集,我怎样才能确保我在队列中或执行过程中没有更多的计时器以避免访问突然被释放的物体。
答案 0 :(得分:3)
根据您的具体实施,有很多不同的方法来解决您的问题。很少有基本想法可以:
定义一个布尔值,指定播放器是否正在运行(true = running,false = not)
在每次与玩家相关的通话之前,检查该变量及其是否为假(玩家停止),关闭该功能(立即返回)
然后,您调用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帖子中解释所有竞争条件规避策略。 如果您需要提高性能,则应准确定义代码的并发问题并选择正确的策略。