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参数说明
1SDL_ThreadFunction fn线程所调用的函数
2const char *name 线程的名称
3void *data 线程所传入的数据
4pfnSDL_CurrentBeginThread pfnBeginThread 开始线程
5pfnSDL_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.  
  11. #else
  12.  
  13. /**
  14. * Create a thread.
  15. *
  16. * Thread naming is a little complicated: Most systems have very small
  17. * limits for the string length (Haiku has 32 bytes, Linux currently has 16,
  18. * Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll
  19. * have to see what happens with your system's debugger. The name should be
  20. * UTF-8 (but using the naming limits of C identifiers is a better bet).
  21. * There are no requirements for thread naming conventions, so long as the
  22. * string is null-terminated UTF-8, but these guidelines are helpful in
  23. * choosing a name:
  24. *
  25. * http://stackoverflow.com/questions/149932/naming-conventions-for-threads
  26. *
  27. * If a system imposes requirements, SDL will try to munge the string for
  28. * it (truncate, etc), but the original string contents will be available
  29. * from SDL_GetThreadName().
  30. */
  31. extern DECLSPEC SDL_Thread *SDLCALL
  32. SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
  33.  
  34. #endif

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

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

 

ID参数说明
1SDL_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参数说明
1Uint32 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参数说明
1SDL_Thread * thread所等待的线程
2int *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参数说明
1int返回参数 返回0或1,如果返回错误将继续等下一个事件
2SDL_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.  
  32. /* This is necessary for ABI compatibility between Visual C++ and GCC
  33. Visual C++ will respect the push pack pragma and use 52 bytes for
  34. this structure, and GCC will use the alignment of the largest datatype
  35. within the union, which is 8 bytes.
  36.  
  37. So... we'll add padding to force the size to be 56 bytes for both.
  38. */
  39. Uint8 padding[56];
  40. } 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. /**
  10. * Try to lock the mutex
  11. *
  12. * \return 0, SDL_MUTEX_TIMEDOUT, or -1 on error
  13. */
  14. 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参数说明
1SDL_cond * cond条件变量
2SDL_mutex * mutexSDL互斥对象

 

 
  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参数说明
1SDL_cond * cond条件变量
2SDL_mutex * mutexSDL互斥对象
3Uint32 ms超时时间,单位毫秒

 


代码实例:

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

 

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

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

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

 

实际输出结果如下:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值