SDL线程使用
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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);
扩展定义
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.
* /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
2、SDL_Delay
原始定义
1.
/**2.
* \brief Wait a specified number of milliseconds before returning.3.
*/4. extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms);
ID
参数说明1
SDL_ThreadFunction fn 线程所调⽤的函数2
const char *name 线程的名称3
void *data 线程所传⼊的数据4
pfnSDL_CurrentBeginThread pfnBeginThread 开始线程5
pfnSDL_CurrentEndThread pfnEndThread 结束线程
ID
参数说明1
SDL_ThreadFunction fn 线程所调⽤的函数2
const char *name 线程的名称3 void *data 线程所传⼊的数据
本质上说,这个函数类似与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_LockMutex和SDL_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 * 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参数说明
1SDL_cond * cond条件变量
2SDL_mutex * mutex SDL互斥对象
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 来结束整个程序。
实际输出结果如下:。