前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【FFmpeg】SDL 音视频开发 ④ ( SDL 多线程 | SDL_Thread 结构体 | SDL_CreateThread 函数创建线程 | SDL_WaitThread 函数等待线程执行 )

【FFmpeg】SDL 音视频开发 ④ ( SDL 多线程 | SDL_Thread 结构体 | SDL_CreateThread 函数创建线程 | SDL_WaitThread 函数等待线程执行 )

作者头像
韩曙亮
发布2024-06-19 13:11:04
890
发布2024-06-19 13:11:04
举报

博客源码下载 :

SDL 多线程模型 代码执行效果如下 :

一、SDL 多线程简介

1、SDL 多线程引入

SDL 支持 多线程 编程 , 开发者 可以 创建多个线程 , 来执行不同的任务 , 如开启多个线程同时处理

  • 处理音视频同步
  • 视频画面渲染
  • 音视频解码

SDL 多线程 可以 提高 程序的性能 和 响应能力 , 可以更好的处理 音视频编解码、视频渲染 这种大量数据计算的场景 ;

SDL 多线程 是 跨平台 的 , 编写完的 SDL 多线程代码可以在多个平台运行 ;

  • 在 Windows 系统中 , 会生成 Windows 的多线程 模块 ;
  • 在 Linux 系统中 , 会生成对应 Linux 的多线程 模块 ;
  • 在 MacOS 系统中 , 会生成 MacOS 的多线程 模块 ;

2、SDL_Thread 多线程模型

SDL_Thread 是 SDL 开发库中 用于 表示线程的 结构体 类型 , 其中包含了 线程标识符 和 线程其它信息 ;

SDL_Thread 结构体定义在 SDL_thread.h 头文件中 ;

代码语言:javascript
复制
/* SDL 线程 结构体 , 定义在 SDL_thread.c 中 */
struct SDL_Thread;
typedef struct SDL_Thread SDL_Thread;

SDL_Thread 提供了对线程的 基本管理和控制 功能 , 该结构体对象 是 通过 SDL_CreateThread 函数创建的 ;

SDL_Thread 结构体 一般 不需要直接访问其内部字段 , 而是通过 SDL 提供的一系列函数来操作线程 , 如 :

  • SDL_CreateThread 函数 创建线程 ;
  • SDL_WaitThread 函数 阻塞等待指定线程结束 ;

二、SDL 多线程相关函数

1、SDL 创建线程 - SDL_CreateThread 函数

SDL_CreateThread 函数 的 作用是 创建 SDL 线程 , 函数原型 如下 :

代码语言:javascript
复制
SDL_Thread* SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
  • fn 参数 : 函数指针 , 指向线程要执行的函数 ; 该函数参数类型为 void* , 返回值类型为 int ;
  • name 参数 : 线程名称 , 调试代码时使用该参数 ;
  • data 参数 : 传递给线程函数的数据指针 , 具体就是向 fn 参数 指向的 线程函数 中传入的 参数 ;
  • SDL_Thread* 类型返回值 :
    • 如果 线程创建成功 , 返回一个指向 SDL_Thread 结构体的指针 ;
    • 如果 线程创建失败 , 返回 NULL ;

SDL_ThreadFunction fn 参数 是 函数指针 , 其指向的函数需要符合以下形式要求 :

代码语言:javascript
复制
int threadFunction(void *data);
  • data 参数 : void* 类型的指针 , 指向一个指定类型的数据 ;
  • int 返回值 : 返回 int 类型的数据作为返回值 , 这个值是 退出状态 ;

下面的 threadFunction 函数 , 就是符合上述 SDL_ThreadFunction fn 参数标准的函数 , 该函数可以传入到 SDL_CreateThread 函数中 , 作为第一个参数使用 ;

代码语言:javascript
复制
int threadFunction(void *data) {
    // 先将 void * 类型的指针 data 转为 int * 类型的指针
    // 然后使用 * 运算符获取 int * 类型指针指向的数据
    int thread_id = *((int *)data);

    // 打印 传入的数据
    printf("Thread %d is running\n", thread_id);

    // 延迟 2 秒
    SDL_Delay(2000);

    // 打印 传入的数据
    printf("Thread %d finished\n", thread_id);

    // 返回退出状态位
    return 0;
}

创建线程代码示例如下 :

代码语言:javascript
复制
    // 准备线程数据
    int a = 666;

    // 创建线程
    SDL_Thread *thread1 = SDL_CreateThread(threadFunction, "Thread 1", (void *)&a);

2、SDL 等待线程执行完毕 - SDL_WaitThread 函数

SDL_WaitThread 函数 的作用是 等待线程结束 , 并获取退出状态 ;

SDL_WaitThread 函数 执行时 会 阻塞 当前代码 , 以等待 指定的线程 执行完毕 ;

SDL_WaitThread 函数原型 :

代码语言:javascript
复制
/**
 * 等待一个线程执行结束。没有被分离的线程将保持为“僵尸”状态,直到此函数清理它们。
 * 不进行清理会导致资源泄漏。
 *
 * 一旦通过此函数清理了一个线程,引用它的 SDL_Thread 将变为无效,不应再次引用。
 * 因此,只能有一个线程调用 SDL_WaitThread() 来等待另一个线程。
 *
 * 如果 \c status 不为 NULL,则线程函数的返回代码将放置在 \c status 指向的区域。
 *
 * 不能等待已经通过 SDL_DetachThread() 调用的线程。要么使用该函数,要么使用此函数,
 * 但不要同时使用两者,否则行为未定义。
 *
 * 将 NULL 传递给此函数是安全的;它不执行任何操作。
 */
extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status);
代码语言:javascript
复制
void SDL_WaitThread(SDL_Thread * thread, int *status);
  • thread 参数 : 指向 SDL_Thread 结构的指针 , 指向要等待执行结束的线程 ;
  • status 参数 : 指向整数的指针 , 用于接收线程的退出状态 , 相当于接收一个返回值 ;

这个 接收线程退出状态 的值 , 就是 SDL_CreateThread 函数中传入的第一个参数 int threadFunction(void *data) 函数的返回值 ;

代码示例 :

代码语言:javascript
复制
    // 准备线程数据
    int a = 666;

    // 创建线程
    SDL_Thread *thread = SDL_CreateThread(threadFunction, "Thread 1", (void *)&a);

    // 等待线程结束 , 并获取退出状态
    int threadReturnValue;
    SDL_WaitThread(thread, &threadReturnValue);

三、SDL 线程代码示例 - 创建并等待线程执行完毕

1、代码示例

在下面的代码中 , 初始化 SDL 环境 和 退出 SDL 环境 , 分别调用了 SDL_Init 和 SDL_Quit 函数 ;

SDL 线程执行步骤如下 :

  • 首先 , 定义了 int threadFunction(void *data) 类型的线程函数 ;
  • 然后 , 调用 SDL_CreateThread 函数 , 创建了线程 , 将 int 类型变量 666 的地址传递给了 线程函数 中 ;
  • 最后 , 调用 SDL_WaitThread 函数 , 阻塞等待上述 线程函数 执行完毕 ;

代码示例 :

代码语言:javascript
复制
#include <stdio.h>
#include <SDL.h>

int threadFunction(void *data) {
    // 先将 void * 类型的指针 data 转为 int * 类型的指针
    // 然后使用 * 运算符获取 int * 类型指针指向的数据
    int thread_id = *((int *)data);

    // 打印 传入的数据
    printf("Thread %d is running\n", thread_id);

    // 延迟 2 秒
    SDL_Delay(2000);

    // 打印 传入的数据
    printf("Thread %d finished\n", thread_id);

    // 返回退出状态位
    return 888;
}

#undef main
int main(int argc, char* argv[])
{
    printf("Hello World!\n");

    SDL_Init(SDL_INIT_VIDEO);

    // 准备线程数据
    int a = 666;

    // 创建线程
    SDL_Thread *thread = SDL_CreateThread(threadFunction, "Thread 1", (void *)&a);

    // 等待线程结束 , 并获取退出状态
    int threadReturnValue;
    SDL_WaitThread(thread, &threadReturnValue);

    printf("Thread returned threadReturnValue : %d\n", threadReturnValue);

    // 释放 SDL 资源
    SDL_Quit();

    return 0;
}

2、执行结果

执行结果 :

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、SDL 多线程简介
    • 1、SDL 多线程引入
      • 2、SDL_Thread 多线程模型
      • 二、SDL 多线程相关函数
        • 1、SDL 创建线程 - SDL_CreateThread 函数
          • 2、SDL 等待线程执行完毕 - SDL_WaitThread 函数
          • 三、SDL 线程代码示例 - 创建并等待线程执行完毕
            • 1、代码示例
              • 2、执行结果
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档