2.使用线程方式获取标准输入
前面讲到,使用非阻塞方式有许多的缺点。主要是单线程,一直占用CPU资源,其他程序无法执行,造成资源的浪费。只能用于较简单循环的场所。而线程灵活,CPU占用率小,适用于大部分场合。
1.条件变量的使用
条件变量是用来通知共享数据的状态信息的机制。由于涉及共享数据,所以一般和互斥量配合使用。
1.1创建和销毁条件变量
pthread_cond_t表示条件变量。在使用pthread_cond_t变量前对其进行初始化。使用默认属性,可以用PTHREAD_COND_INITIALIZER付给变量就可以完成初始化。
pthread_cond_desroy销毁一个条件变量。函数形式为
pthread_cond_desroy(pthread_cond_t * cond)
1.2等待和通知条件变量
条件变量与条件测试是一起调用的。如果测试失败,则调用pthread_cond_wait
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex)
如果测试成功,则调用pthread_cond_signal函数。
int pthread_cond_signal(pthread_cond_t *cond)
pthread_cond_signal函数只唤醒一个阻塞在cond指向的条件变量上的线程。
2条件变量的应用
2.1 在AllInputDevicesInit函数内创建线程
1 if (0 == ptTmp->DeviceInit())
2 {
3 /* 创建子线程 */
4 pthread_create(&ptTmp->tTreadID, NULL, InputEventTreadFunction, ptTmp->GetInputEvent);
5 iError = 0;
6 }
7 ptTmp = ptTmp->ptNext; 实现InputEventTreadFunction函数
1 static void *InputEventTreadFunction(void *pVoid)
2 {
3 T_InputEvent tInputEvent;
4
5 /* 定义函数指针 */
6 int (*GetInputEvent)(PT_InputEvent ptInputEvent);
7 GetInputEvent = (int (*)(PT_InputEvent))pVoid;
8
9 while (1)
10 {
11 if(0 == GetInputEvent(&tInputEvent))
12 {
13 /* 唤醒主线程, 把tInputEvent的值赋给一个全局变量 */
14 /* 访问临界资源前,先获得互斥量 */
15 pthread_mutex_lock(&g_tMutex);
16 g_tInputEvent = tInputEvent;
17
18 /* 唤醒主线程 */
19 pthread_cond_signal(&g_tConVar);
20
21 /* 释放互斥量 */
22 pthread_mutex_unlock(&g_tMutex);
23 }
24 }
25
26 return NULL;
27 } 2.2在Touchscreen.c里全改为阻塞方式
TouchScreenGetInputEvent函数修改如下:
1 static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent)
2 {
3 struct ts_sample tSamp;
4 struct ts_sample tSampPressed;
5 struct ts_sample tSampReleased;
6 int iRet;
7 int bStart = 0;
8 int iDelta;
9
10 static struct timeval tPreTime;
11
12
13 while (1)
14 {
15 iRet = ts_read(g_tTSDev, &tSamp, 1); /* 如果无数据则休眠 */
16 if (iRet == 1)
17 {
18 if ((tSamp.pressure > 0) && (bStart == 0))
19 {
20 /* 刚按下 */
21 /* 记录刚开始压下的点 */
22 tSampPressed = tSamp;
23 bStart = 1;
24 }
25
26 if (tSamp.pressure <= 0)
27 {
28 /* 松开 */
29 tSampReleased = tSamp;
30
31 /* 处理数据 */
32 if (!bStart)
33 {
34 return -1;
35 }
36 else
37 {
38 iDelta = tSampReleased.x - tSampPressed.x;
39 ptInputEvent->tTime = tSampReleased.tv;
40 ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN;
41
42 if (iDelta > giXres/5)
43 {
44 /* 翻到上一页 */
45 ptInputEvent->iVal = INPUT_VALUE_UP;
46 }
47 else if (iDelta < 0 - giXres/5)
48 {
49 /* 翻到下一页 */
50 ptInputEvent->iVal = INPUT_VALUE_DOWN;
51 }
52 else
53 {
54 ptInputEvent->iVal = INPUT_VALUE_UNKNOWN;
55 }
56 return 0;
57 }
58 }
59 }
60 else
61 {
62 return -1;
63 }
64 }
65
66 return 0;
67 } 上述程序主要实现:触摸点在x方向上的位移差值超过X分辨率的1/5,就翻页,从而实现滑动翻页。
相关推荐
arctan0 2020-10-14
hackerlpy 2020-09-25
大唐帝国前营 2020-08-18
yuanlu 2020-08-17
chunjiekid 2020-08-16
cuiweisaidelike 2020-08-02
comeonxueRong 2020-08-02
zzqLivecn 2020-07-09
yunfeitian 2020-07-05
hell0kitty 2020-07-04
TreasureZ 2020-06-25
阿亮 2020-06-21
瓜牛呱呱 2020-11-12
Charlesbases 2020-10-23
温攀峰 2020-09-16
天空一样的蔚蓝 2020-09-04
ericxieforever 2020-09-03