SDL线程使用

1、SDL_CreateThread

原始定义

  1. /**
  2. * Create a thread.
  3. */
  4. extern DECLSPEC SDL_Thread *SDLCALL
  5. SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
  6. pfnSDL_CurrentBeginThread pfnBeginThread,
  7. pfnSDL_CurrentEndThread pfnEndThread);
ID 参数 说明
1 SDL_ThreadFunction fn 线程所调用的函数
2 const char *name  线程的名称
3 void *data  线程所传入的数据
4 pfnSDL_CurrentBeginThread pfnBeginThread  开始线程
5 pfnSDL_CurrentEndThread pfnEndThread  结束线程

扩展定义

  1. /**
  2. * Create a thread.
  3. */
  4. #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
  5. #undef SDL_CreateThread
  6. #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
  7. #else
  8. #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
  9. #endif
  10. #else
  11. /**
  12. * Create a thread.
  13. *
  14. * Thread naming is a little complicated: Most systems have very small
  15. * limits for the string length (Haiku has 32 bytes, Linux currently has 16,
  16. * Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You‘ll
  17. * have to see what happens with your system‘s debugger. The name should be
  18. * UTF-8 (but using the naming limits of C identifiers is a better bet).
  19. * There are no requirements for thread naming conventions, so long as the
  20. * string is null-terminated UTF-8, but these guidelines are helpful in
  21. * choosing a name:
  22. *
  23. * http://stackoverflow.com/questions/149932/naming-conventions-for-threads
  24. *
  25. * If a system imposes requirements, SDL will try to munge the string for
  26. * it (truncate, etc), but the original string contents will be available
  27. * from SDL_GetThreadName().
  28. */
  29. extern DECLSPEC SDL_Thread *SDLCALL
  30. SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
  31. #endif

由定义可知在扩展定义中参数仅有三个比标准定义要少两。

在其宏定义中可以发现扩展定义中直接将参数后两项定义为NULL

ID 参数 说明
1 SDL_ThreadFunction fn 线程所调用的函数
2  const char *name 线程的名称
3  void *data 线程所传入的数据

2、SDL_Delay

原始定义

  1. /**
  2. * \brief Wait a specified number of milliseconds before returning.
  3. */
  4. extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms);

本质上说,这个函数类似与Windows多线程中的Sleep

ID 参数 说明
1 Uint32 ms 已毫秒为单位的数值

3、SDL_WaitThread

原始定义

  1. /**
  2. * Wait for a thread to finish. Threads that haven‘t been detached will
  3. * remain (as a "zombie") until this function cleans them up. Not doing so
  4. * is a resource leak.
  5. *
  6. * Once a thread has been cleaned up through this function, the SDL_Thread
  7. * that references it becomes invalid and should not be referenced again.
  8. * As such, only one thread may call SDL_WaitThread() on another.
  9. *
  10. * The return code for the thread function is placed in the area
  11. * pointed to by \c status, if \c status is not NULL.
  12. *
  13. * You may not wait on a thread that has been used in a call to
  14. * SDL_DetachThread(). Use either that function or this one, but not
  15. * both, or behavior is undefined.
  16. *
  17. * It is safe to pass NULL to this function; it is a no-op.
  18. */
  19. extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status);

等待这个线程直至它完成。

ID 参数 说明
1 SDL_Thread * thread 所等待的线程
2 int *status 返回的线程状态

4、SDL_WaitEvent

原始定义

  1. /**
  2. * \brief Waits indefinitely for the next available event.
  3. *
  4. * \return 1, or 0 if there was an error while waiting for events.
  5. *
  6. * \param event If not NULL, the next event is removed from the queue and
  7. * stored in that area.
  8. */
  9. extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event);
ID 参数 说明
1 int 返回参数 返回0或1,如果返回错误将继续等下一个事件
2 SDL_Event * event 返回SDL_EVENT事件

5、SDL_Event

原始定义

  1. /**
  2. * \brief General event structure
  3. */
  4. typedef union SDL_Event
  5. {
  6. Uint32 type; /**< Event type, shared with all events */
  7. SDL_CommonEvent common; /**< Common event data */
  8. SDL_WindowEvent window; /**< Window event data */
  9. SDL_KeyboardEvent key; /**< Keyboard event data */
  10. SDL_TextEditingEvent edit; /**< Text editing event data */
  11. SDL_TextInputEvent text; /**< Text input event data */
  12. SDL_MouseMotionEvent motion; /**< Mouse motion event data */
  13. SDL_MouseButtonEvent button; /**< Mouse button event data */
  14. SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */
  15. SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */
  16. SDL_JoyBallEvent jball; /**< Joystick ball event data */
  17. SDL_JoyHatEvent jhat; /**< Joystick hat event data */
  18. SDL_JoyButtonEvent jbutton; /**< Joystick button event data */
  19. SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
  20. SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */
  21. SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
  22. SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
  23. SDL_AudioDeviceEvent adevice; /**< Audio device event data */
  24. SDL_QuitEvent quit; /**< Quit request event data */
  25. SDL_UserEvent user; /**< Custom event data */
  26. SDL_SysWMEvent syswm; /**< System dependent window event data */
  27. SDL_TouchFingerEvent tfinger; /**< Touch finger event data */
  28. SDL_MultiGestureEvent mgesture; /**< Gesture event data */
  29. SDL_DollarGestureEvent dgesture; /**< Gesture event data */
  30. SDL_DropEvent drop; /**< Drag and drop event data */
  31. /* This is necessary for ABI compatibility between Visual C++ and GCC
  32. Visual C++ will respect the push pack pragma and use 52 bytes for
  33. this structure, and GCC will use the alignment of the largest datatype
  34. within the union, which is 8 bytes.
  35. So... we‘ll add padding to force the size to be 56 bytes for both.
  36. */
  37. Uint8 padding[56];
  38. } SDL_Event;

6、SDL线程互斥的实现

SDL_mutex

互斥结构体

  1. /* The SDL mutex structure, defined in SDL_sysmutex.c */
  2. struct SDL_mutex;
  3. typedef struct SDL_mutex SDL_mutex;


SDL_CreateMutex

创建一个互斥对象,并初始化为解锁状态

  1. /**
  2. * Create a mutex, initialized unlocked.
  3. */
  4. extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void);

加互斥锁有两种

SDL_LockMutexSDL_TryLockMutex

SDL_LockMutex仅返回0和-1,SDL_TryLockMutex还会返回SDL_TIMEDOUT

  1. /**
  2. * Lock the mutex.
  3. *
  4. * \return 0, or -1 on error.
  5. */
  6. #define SDL_mutexP(m) SDL_LockMutex(m)
  7. extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex);
  8. /**
  9. * Try to lock the mutex
  10. *
  11. * \return 0, SDL_MUTEX_TIMEDOUT, or -1 on error
  12. */
  13. extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex);

解互斥锁函数

  1. /**
  2. * Unlock the mutex.
  3. *
  4. * \return 0, or -1 on error.
  5. *
  6. * \warning It is an error to unlock a mutex that has not been locked by
  7. * the current thread, and doing so results in undefined behavior.
  8. */
  9. #define SDL_mutexV(m) SDL_UnlockMutex(m)
  10. extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex);

释放锁资源

  1. /**
  2. * Destroy a mutex.
  3. */
  4. extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex * mutex);

条件变量

  1. /* The SDL condition variable structure, defined in SDL_syscond.c */
  2. struct SDL_cond;
  3. typedef struct SDL_cond SDL_cond;

 创建条件变量

  1. /**
  2. * Create a condition variable.
  3. *
  4. * Typical use of condition variables:
  5. *
  6. * Thread A:
  7. * SDL_LockMutex(lock);
  8. * while ( ! condition ) {
  9. * SDL_CondWait(cond, lock);
  10. * }
  11. * SDL_UnlockMutex(lock);
  12. *
  13. * Thread B:
  14. * SDL_LockMutex(lock);
  15. * ...
  16. * condition = true;
  17. * ...
  18. * SDL_CondSignal(cond);
  19. * SDL_UnlockMutex(lock);
  20. *
  21. * There is some discussion whether to signal the condition variable
  22. * with the mutex locked or not. There is some potential performance
  23. * benefit to unlocking first on some platforms, but there are some
  24. * potential race conditions depending on how your code is structured.
  25. *
  26. * In general it‘s safer to signal the condition variable while the
  27. * mutex is locked.
  28. */
  29. extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void);

通过条件变量的变化来改变互斥锁的状态。

销毁条件变量

  1. /**
  2. * Destroy a condition variable.
  3. */
  4. extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond);

重启一个正在等待条件变量的线程

  1. /**
  2. * Restart one of the threads that are waiting on the condition variable.
  3. *
  4. * \return 0 or -1 on error.
  5. */
  6. extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond);

重启所有正在等待条件变量的线程

  1. /**
  2. * Restart all threads that are waiting on the condition variable.
  3. *
  4. * \return 0 or -1 on error.
  5. */
  6. extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond);

 条件变量等待

  1. /**
  2. * Wait on the condition variable, unlocking the provided mutex.
  3. *
  4. * \warning The mutex must be locked before entering this function!
  5. *
  6. * The mutex is re-locked once the condition variable is signaled.
  7. *
  8. * \return 0 when it is signaled, or -1 on error.
  9. */
  10. extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex);
ID 参数 说明
1 SDL_cond * cond 条件变量
2 SDL_mutex * mutex SDL互斥对象
  1. /**
  2. * Waits for at most \c ms milliseconds, and returns 0 if the condition
  3. * variable is signaled, ::SDL_MUTEX_TIMEDOUT if the condition is not
  4. * signaled in the allotted time, and -1 on error.
  5. *
  6. * \warning On some platforms this function is implemented by looping with a
  7. * delay of 1 ms, and so should be avoided if possible.
  8. */
  9. extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond,
  10. SDL_mutex * mutex, Uint32 ms);

注:如果超时将发送SDL_TIMEDOUT的超时信号,如果 未发送该信号,那么将返回-1

ID 参数 说明
1 SDL_cond * cond 条件变量
2 SDL_mutex * mutex SDL互斥对象
3 Uint32 ms 超时时间,单位毫秒

代码实例:

  1. // SDL_ThreadTest.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #define __STDC_CONSTANT_MACROS
  5. #define SDL_MAIN_HANDLED
  6. #define SDL_THREAD_FINISH (SDL_USEREVENT+1)
  7. // 导入SDL库
  8. #include "SDL.h"
  9. int i = 0;
  10. SDL_mutex* data_lock;
  11. SDL_cond * cond;
  12. SDL_Thread* pthread1;
  13. SDL_Thread* pthread2;
  14. SDL_Event event;
  15. int SDLThread1(void *data)
  16. {
  17. int * pi = (int*)data;
  18. for (;;)
  19. {
  20. if ((*pi) > 99)
  21. {
  22. SDL_Event event;
  23. event.type = SDL_THREAD_FINISH;
  24. SDL_PushEvent(&event);
  25. break;
  26. }
  27. SDL_LockMutex(data_lock);
  28. (*pi)++;
  29. printf("This is SDL Thread1, Current i is [%d]\n", (*pi));
  30. if ((*pi)==50)
  31. {
  32. SDL_CondSignal(cond);
  33. }
  34. SDL_UnlockMutex(data_lock);
  35. SDL_Delay(10);
  36. }
  37. return 0;
  38. }
  39. int SDLThread2(void *data)
  40. {
  41. int * pi = (int*)data;
  42. for (;;)
  43. {
  44. if ((*pi) > 99)
  45. {
  46. SDL_Event event;
  47. event.type = SDL_THREAD_FINISH;
  48. SDL_PushEvent(&event);
  49. break;
  50. }
  51. SDL_LockMutex(data_lock);
  52. SDL_CondWait(cond, data_lock);
  53. (*pi)++;
  54. printf("This is SDL Thread2, Current i is [%d]\n", (*pi));
  55. SDL_UnlockMutex(data_lock);
  56. SDL_Delay(10);
  57. }
  58. return 0;
  59. }
  60. int main()
  61. {
  62. SDL_Init(SDL_INIT_EVERYTHING);
  63. data_lock = SDL_CreateMutex();
  64. cond = SDL_CreateCond();
  65. pthread1 = SDL_CreateThread(SDLThread1, "Thread1", &i);
  66. pthread2 = SDL_CreateThread(SDLThread2, "Thread2", &i);
  67. for (;;)
  68. {
  69. SDL_WaitEvent(&event);
  70. if (event.type == SDL_THREAD_FINISH)
  71. break;
  72. }
  73. SDL_DestroyCond(cond);
  74. SDL_DestroyMutex(data_lock);
  75. SDL_Quit();
  76. system("pause");
  77. return 0;
  78. }

两个线程操作int i。创建互斥锁data_lock在各线程的操作段锁定i。

然后通过 SDL_cond条件变量设定仅在i值为50时解锁第二个线程。

同时使用自定义SDL_EVENT 来结束整个程序。

实际输出结果如下:

来自为知笔记(Wiz)

时间: 2024-10-12 03:58:39

SDL线程使用的相关文章

FFMPEG + SDL音频播放分析

目录 [hide] 1 抽象流程: 2 关键实现: 2.1 main()函数 2.2 decode_thread()读取文件信息和音频包 2.3 stream_component_open():设置音频参数和打开设备 2.4 audio_callback(): 回调函数,向SDL缓冲区填充数据 2.5 audio_decode_frame():解码音频 3 FFMPEG结构体 3.1 channel_layout_map 4 FFMPEG宏定义 4.1 Audio channel conveni

关于解决用tutorial7教程中的代码打造一款自己的播放器中的声音噪音问题

////////////////////////////////////////////////////////////////////////////////////////////对于用FFMPEG2.01和SDL2.01最新的版本来做音频播放器,这篇文章和版本是很有值得参考的价值这篇文章解决了我在做简易播放器的时候,用tutorial07的代码的时候,声音播放出现杂音的问题出现杂音的问题原因可以从http://blog.csdn.net/leixiaohua1020/article/det

littlevgl架构浅析

一.   littlevgl有几个线程,作用是什么? 三个,主线程一个,和在主线程的hal_init函数中创建的另两个sdl线程. 主线程完成一系列初始化工作后,循环每10ms调用在lv_init函数中注册的三个任务,indev_proc_task,lv_refr_task,anim_task,重点关注的是每50ms处理一次的输入处理indev_proc_task和每30ms处理一次的画面刷新lv_refr_task. monitor_sdl_refr_thread线程负责输出图像和鼠标键盘的输

各科基础详实

一. Java基础部分 1. JAVA的基本数据类型有哪些 ?  String 是不是基本数据类型 ? 2. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 3. Java有没有goto? 7 4. 说说&和&&的区别. 7 5. 在JAVA中如何跳出当前的多重嵌套循环? 7 6. switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 8 7. short s1 = 1; s1 = s1 + 1;有什么

100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】

转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 简介 流程图 simplest_ffmpeg_player标准版代码 simplest_ffmpeg_player_suSU版代码 结果 FFMPEG相关学习资料 补充问题 ===================================================== 最简单的基于FFmp

最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)

===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x) 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0) 最简单的基于FFmpeg的解码器-纯净版(不包括libavformat) 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器 最简单的基于FFMPEG的Hellowor

SDL Guide 中文译版

SDL即Simple DirectMedia Layer,类似DirectX,是完整的游戏.多媒体开发包,但不同的是它跨越几乎所有的平台,有各种语言的接口,多种语言的文档,而这一切都是广大志愿者完成的.目前扩展部分还没有正式的文档,以下为核心部分文档的向导部分. 序言 关于SDL SDL为方便制作能跨跃Linux.BSD.MacOS.Win32和BeOS平台,使用本地高性能媒体接口,并且让您可以只需使用一份源代码级API而设计.SDL是相当低层的API,但使用它可以让你以极大的灵活性写出完全跨平

SDL 简介

SDL 简介 什么是SDL? 即 Simple DirectMedia Layer,使用 LGPL 许可证. 免费的跨平台多媒体应用编程接口 用于游戏.游戏开发工具.模拟器.样本演示.多媒体应用等 它能做什么? 视频.音频.事件.CDROM支持.线程.计时器.各种图象文件格式读取.快速绘图.混音.游戏杆支持.网络.MPEG解码等等,且CPU字节顺序无关. 大体上与DirectX比较对应关系如下: SDL_Video.SDL_Image.OpenGL -- DirectDraw.Direct3D

ffmpeg实战教程(二)用SDL播放YUV,并结合ffmpeg实现简易播放器

我们先实现用SDL播放YUV数据 先来了解一下基本概念 SDL基本函数: [初始化] * SDL_Init(): 初始化SDL. * SDL_CreateWindow(): 创建窗口(Window). * SDL_CreateRenderer(): 基于窗口创建渲染器(Render). * SDL_CreateTexture(): 创建纹理(Texture). [循环渲染数据] * SDL_UpdateTexture(): 设置纹理的数据. * SDL_RenderCopy(): 纹理复制给渲染