我们开发android的时候知道,主线程不能执行耗时的操作,否者的话就会导致ANR错误。
SDL的开发也同样不能在主线程执行耗时操作,或者就会导致播放器接收不到我们的输入操作。
SDL创建线程的函数如下:
SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
fn 要执行的函数
name 线程的名字
data 执行函数的参数 可以是任何类型的指针。
线程的互斥与同步
互斥:资源某一时刻只能有一个线程访问(锁)
同步:一个线程完成了,通过信号通知第二线程再开始执行。就像流水线一样。(信号)
锁的种类:
互斥锁。
读写锁。
自旋锁。
可重入锁:对当前线程可以重复进入,其他线程不能进入。
互斥锁和读写锁的区别。
互斥锁:等待时,让出CPU,等待其他线程释放互斥锁,通过信号唤醒当前线程。
自旋锁:等待时,不让出CPU,循坏检查当前锁是否被释放,释放后当前线程执行。
通过对比,我们知道自旋锁加锁旗舰,执行线程不能耗时太长。
SDL 只提供了互斥锁
extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void);
extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex * mutex);
上锁与释放锁
extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex);
extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex);
信号量:
extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void);
extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond);
extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex);
#include <stdio.h>
#include <SDL2/SDL.h>
static SDL_mutex *m_mutex;
static SDL_cond *m_cond;
static int first_end = 0;
static int second_end = 0;
int first_func_print()
{
SDL_LockMutex(m_mutex);
for (int i = 0; i < 5; i++)
{
printf("first_func_print %d\n", i);
}
SDL_CondSignal(m_cond);
SDL_CondWait(m_cond, m_mutex);
for (int i = 5; i < 10; i++)
{
printf("first_func_print %d\n", i);
}
first_end = 1;
SDL_UnlockMutex(m_mutex);
return 1;
}
int second_func_print()
{
SDL_LockMutex(m_mutex);
for (int i = 0; i < 5; i++)
{
printf("second_func_print %d\n", i);
}
SDL_CondSignal(m_cond);
second_end = 1;
SDL_UnlockMutex(m_mutex);
return 1;
}
int main(int argc, char *argv[])
{
m_mutex = SDL_CreateMutex();
m_cond = SDL_CreateCond();
SDL_CreateThread(first_func_print, "first_func_print", NULL);
SDL_CreateThread(second_func_print, "second_func_print", NULL);
while(!first_end || !second_end){
}
printf("print end \n");
SDL_DestroyCond(m_cond);
SDL_DestroyMutex(m_mutex);
SDL_Quit();
}