zoukankan      html  css  js  c++  java
  • 2.使用线程方式获取标准输入

    前面讲到,使用非阻塞方式有许多的缺点。主要是单线程,一直占用CPU资源,其他程序无法执行,造成资源的浪费。只能用于较简单循环的场所。而线程灵活,CPU占用率小,适用于大部分场合。

    1.条件变量的使用

    条件变量是用来通知共享数据的状态信息的机制。由于涉及共享数据,所以一般和互斥量配合使用。

    1.1创建和销毁条件变量

    pthread_cond_t表示条件变量。在使用pthread_cond_t变量前对其进行初始化。使用默认属性,可以用PTHREAD_COND_INITIALIZER付给变量就可以完成初始化。

    pthread_cond_desroy销毁一个条件变量。函数形式为

    1 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函数。

    1 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,就翻页,从而实现滑动翻页。

  • 相关阅读:
    三行代码搞定微信登录集成
    iptables命令
    Linux(centos)系统各个目录的作用详解 推荐
    Linux下Apache服务的查看和启动
    Linux使用退格键时出现^H ^?解决方法
    小程序:最难点For的wx:key
    linux 通过wol远程开机【转】
    linux wake on lan功能通过ethtool配置【转】
    设计模式小议:state【转】
    TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute【转】
  • 原文地址:https://www.cnblogs.com/Lwd-linux/p/6225439.html
Copyright © 2011-2022 走看看