轮询/select/多线程 对比
轮询:一直查找,CPU占用率高
select:等待内核唤醒, CPU占用率低,适用于很多简单场合
多线程:等待子线程唤醒主线程,CPU占用率低,非常灵活
创建线程
在AllInputDevicesInit函数中创建线程,
创建子线程 pthread_create(pthread_t , attr, start_routine, arg);
pthread_t是线程ID,attr = NULL ,
start_routine是线程开始的调用函数(void * start_routine(void * arg)),
arg是start_routine的参数
//创建线程
int AllInputDevicesInit(void)
{
PT_InputOpr ptTmp = g_ptInputOprHead;
int iError = -1;
while (ptTmp)
{
if (0 == ptTmp->DeviceInit())
{
/* 创建子线程 pthread_create(pthread_t , attr, start_routine, arg);
pthread_t是线程ID,attr = NULL ,
start_routine是线程开始的调用函数(void * start_routine(void * arg)),
arg是start_routine的参数*/
pthread_create(&ptTmp->tTreadID, NULL, InputEventTreadFunction, ptTmp->GetInputEvent);
iError = 0;
}
ptTmp = ptTmp->ptNext;
}
return iError;
}
线程调用函数:start_routine
执行子线程函数,这里等待并得到event值,唤醒主线程
//等待并得到event值
static void *InputEventTreadFunction(void *pVoid)
{
T_InputEvent tInputEvent;
/* 定义函数指针 */
int (*GetInputEvent)(PT_InputEvent ptInputEvent);
GetInputEvent = (int (*)(PT_InputEvent))pVoid;
while (1)
{
//这里GetInputEvent要改成阻塞,如果还是非阻塞,就一直查找,浪费资源
if(0 == GetInputEvent(&tInputEvent))
{
/* 唤醒主线程, 把tInputEvent的值赋给一个全局变量 */
/* 访问临界资源前,先获得互斥量 */
pthread_mutex_lock(&g_tMutex);
//把tInputEvent的值赋给一个全局变量
g_tInputEvent = tInputEvent;
/* 唤醒主线程 */
pthread_cond_signal(&g_tConVar);
/* 释放互斥量 */
pthread_mutex_unlock(&g_tMutex);
}
}
return NULL;
}
主线程函数:等待子线程的唤醒
event值返回给main,把InputEventTreadFunction得到的全局变量的值(event值)通过GetInputEvent的形参传递给main函数
int GetInputEvent(PT_InputEvent ptInputEvent)
{
/* 休眠 */
pthread_mutex_lock(&g_tMutex);
pthread_cond_wait(&g_tConVar, &g_tMutex);
/* 被唤醒后,返回数据 */
*ptInputEvent = g_tInputEvent;
pthread_mutex_unlock(&g_tMutex);
return 0;
}
thread 使用示例
参考 Unix_Linux_Windows_OpenMP多线程编程.pdf P18 3.3.2 条件变量