文章目录
- 一、SDL 多线程简介
- 1、SDL 多线程引入
- 2、SDL_Thread 多线程模型
- 二、SDL 多线程相关函数
- 1、SDL 创建线程 - SDL_CreateThread 函数
- 2、SDL 等待线程执行完毕 - SDL_WaitThread 函数
- 三、SDL 线程代码示例 - 创建并等待线程执行完毕
- 1、代码示例
- 2、执行结果
博客源码下载 :
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 头文件中 ;
/* 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 线程
SDL_Thread* SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
- fn 参数 : 函数指针 , 指向线程要执行的函数
- name 参数 : 线程名称
- data 参数 : 传递给线程函数的数据指针 , 具体就是向 fn 参数 指向的 线程函数 中传入的 参数 ;
- SDL_Thread* 类型返回值 :
- 如果 线程创建成功 , 返回一个指向 SDL_Thread 结构体的指针 ;
- 如果 线程创建失败 , 返回 NULL ;
SDL_ThreadFunction fn 参数 是 函数指针 , 其指向的函数需要符合以下形式要求 :
int threadFunction(void *data);
- data 参数 : void* 类型的指针 , 指向一个指定类型的数据 ;
- int 返回值 : 返回 int 类型的数据作为返回值 , 这个值是 退出状态 ;
下面的 threadFunction 函数 , 就是符合上述 SDL_ThreadFunction fn
参数标准的函数 , 该函数可以传入到 SDL_CreateThread 函数中 , 作为第一个参数使用 ;
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;
}
创建线程代码示例如下 :
// 准备线程数据
int a = 666;
// 创建线程
SDL_Thread *thread1 = SDL_CreateThread(threadFunction, "Thread 1", (void *)&a);
2、SDL 等待线程执行完毕 - SDL_WaitThread 函数
SDL_WaitThread 函数 的作用是 等待线程结束 , 并获取退出状态 ;
SDL_WaitThread 函数 执行时 会 阻塞 当前代码 , 以等待 指定的线程 执行完毕 ;
SDL_WaitThread 函数原型 :
/**
* 等待一个线程执行结束。没有被分离的线程将保持为“僵尸”状态,直到此函数清理它们。
* 不进行清理会导致资源泄漏。
*
* 一旦通过此函数清理了一个线程,引用它的 SDL_Thread 将变为无效,不应再次引用。
* 因此,只能有一个线程调用 SDL_WaitThread() 来等待另一个线程。
*
* 如果 \c status 不为 NULL,则线程函数的返回代码将放置在 \c status 指向的区域。
*
* 不能等待已经通过 SDL_DetachThread() 调用的线程。要么使用该函数,要么使用此函数,
* 但不要同时使用两者,否则行为未定义。
*
* 将 NULL 传递给此函数是安全的;它不执行任何操作。
*/
extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status);
void SDL_WaitThread(SDL_Thread * thread, int *status);
- thread 参数 : 指向 SDL_Thread 结构的指针 , 指向要等待执行结束的线程 ;
- status 参数 : 指向整数的指针 , 用于接收线程的退出状态 , 相当于接收一个返回值 ;
这个 接收线程退出状态 的值 , 就是 SDL_CreateThread 函数中传入的第一个参数 int threadFunction(void *data)
函数的返回值 ;
代码示例 :
// 准备线程数据
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 函数 , 阻塞等待上述 线程函数 执行完毕 ;
代码示例 :
#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、执行结果
执行结果 :