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

Wil*_*ann 5 c multithreading sdl ffmpeg sdl-2

我正在写一个基于FFmpeg的媒体播放器,我有一个设计问题.我的代码调用一个函数,使用SDL的SDL_AddTimer函数以不规则的间隔渲染视频帧.我的问题是,如果我想在一个视频结束(或播放停止)和另一个视频开始时执行垃圾收集,我怎样才能确保我在队列中或执行过程中没有更多的计时器以避免访问突然被释放的物体.

Ale*_*eau 3

根据您的具体实现,有很多不同的方法可以解决您的问题。一些基本想法可以是:

  1. 定义一个布尔值,指定玩家是否正在运行(true = 运行,false = 未运行)

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

  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); 
}
Run Code Online (Sandbox Code Playgroud)

当然,我无法在一篇简单的 stackoverflow 帖子中解释所有竞争条件避免策略。如果您需要提高性能,您应该准确定义代码的并发问题并选择正确的策略。