10.1、android輸入系統_必備Linux編程知識_inotify和epoll

來源:互聯網
上載者:User

標籤:sizeof   printf   檢測   ems   一個   sys   types   rdo   檔案   

1. inotify和epoll

怎麼監測鍵盤接入與拔出?

(1)hotplug機制:核心發現鍵盤接入/拔出==>啟動hotplug進程==>發訊息給輸入系統

(2)inotify機制:輸入系統使用inotify來監測目錄/dev/input

android使用inofity機制

 

當插入多個鍵盤時,系統怎麼知道哪個鍵盤被按下?

android下使用epoll,可以同時監控多個檔案,當檔案發生改變,其會知道誰變化了

 

參考代碼:
frameworks\native\services\inputflinger\EventHub.cpp

參考文章:
《深入理解Android 卷III》第五章 深入理解Android輸入系統 
http://blog.csdn.net/innost/article/details/47660387

 

inotify的使用(監測目錄或者檔案的變化)

(1)fd = inotify_init()

(2)inotify_add_watch(目錄名字/檔案名稱字,建立/刪除)

(3)read(fd),平時目錄和檔案沒有建立或者刪除時,會休眠,發生變化後read返回多個inotify_event結構體

inotify_event.name儲存了名字,inotify_event.len表示名字的長度,inotify_event.mask表示發生了說明變化(建立還是刪除)

 

inotify.c編寫(Usage:inotify <dir> 這個目錄下發生的變化)

#include <unistd.h>

#include <stdio.h>

#include <sys/inotify.h>

#include <string.h>

#include <errno.h>

int read_process_inotify_fd(int fd){

  int res;

  char event_buf[512];

  int event_size;

  int event_pos = 0;

  struct inotify_event *event;

  res = read(fd,event_buf,sizeof(event_buf));

  if(res < (int)sizeof(*event)){

    if(errno == EINTR)

      return 0;

    printf("could not get event ,%s\n",strerror(errno));

    return -1;

  }

  //處理資料,讀到的資料是一個或多個inotify_event,他們len不一樣,逐個處理

  while(res >= (int)sizeof(*event)){

    event = (struct inotify_event *)(event_buf+event_pos);

    if(event->len){

      if(event->mask & IN_CREATE){

          printf("create file : %s\n",event->name);

      }else{

          printf("delete file : %s\n",event->name);

      }

    }

    event_size = sizeof(*event)+event->len;

    res -= event_size;

    event_pos += event_size;

  }

  return 0;

}

 

int main(int argc,char **argv)

{

  int mINotifyFd;

  int result;

  if(argc != 2)

  {

    printf("Usage:%s <dir>\n",argv[0]);

    return -1;

  }

  mINotifyFd = inotify_init();

  result = inotify_add_watch(mINotifyFd,argv[1],IN_DELETE | IN_CREATE);

  while(1)

  {

    read_process_inotify_fd(mINotifyFd);

  }

  return 0;

 

}
gcc -o inotify inotify.c
mkdir tmp
./inotify tmp &

echo > tmp/1
echo > tmp/2
rm tmp/1 tmp/2

 

epoll用來檢測多個檔案有無資料供讀出、有無空間供寫入

(1)epoll_create//建立fd

(2)對每個檔案執行epoll_ctl(......,EPOLL_CTL_ADD,) 表示要監測它

(3)epoll_wait//等待某個檔案可用

(4)不在想監測某檔案可用執行epoll_ctl(......,EPOLL_CTL_DEL,)


epoll , fifo :
http://stackoverflow.com/questions/15055065/o-rdwr-on-named-pipes-with-poll

使用fifo是, 我們的epoll程式是reader
echo aa > tmp/1 是writer
a.
如果reader以 O_RDONLY|O_NONBLOCK開啟FIFO檔案,
當writer寫入資料時, epoll_wait會立刻返回;
當writer關閉FIFO之後, reader再次調用epoll_wait, 它也會立刻返回(原因是EPPLLHUP, 描述符被掛斷)
b.
如果reader以 O_RDWR開啟FIFO檔案
當writer寫入資料時, epoll_wait會立刻返回;
當writer關閉FIFO之後, reader再次調用epoll_wait, 它並不會立刻返回, 而是繼續等待有資料

epoll.c

/*Usage:epoll <file1> [file2] [file3]*/

#include <sys/epoll.h>

#include <unistd.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <string.h>

#define DATA_MAX_LEN 500

int add_to_epoll(int fd,int epollFd)

{

  int result;

  struct epoll_event eventItem;

  memset(&eventItem,0,sizeof(eventItem));

  eventItem.events = EPOLLIN;//表示監測其有資料

  eventItem.data.fd=fd;

  result = epoll_ctl(epollFd,EPOLL_CTL_ADD,fd,&eventItem);

  return result;

}

void rm_from_epoll(int fd,int epollFd)

{

  result = epoll_ctl(epollFd,EPOLL_CTL_DEL,fd,NULL);

}

int main(int argc,char **argv)

{

  int mEpollFd;

  int i;

  char buf[DATA_MAX_LEN];

  static const int EPOLL_MAX_EVENTS = 16;//epoll_wait一次最大監測事件數目

  struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS];

  if(argc < 2)

  {

    printf("Usage:%s<file1> [file2] [file3] \n",argv[0]);

    return -1;

  }

  mEpollFd = epoll_create(8);

  /*for each file:open it /add it to epoll*/

  for(i = 1;i < argc;i++)

  {

    int tmpFd = open(argv[i],O_RDWR);

    add_to_epoll(tmpFd,mEpollFd);

  }

  /*epoll_wait*/

  while(1){

    int pollResult = epoll_wait(mEpollFd ,mPendingEventItems,EPOLL_MAX_EVENTS ,-1);//-1表示永遠監測不退出

    for(i=0;i<pollResult;i++)

    {

      int len =read(mPendingEventItems[i].data.fd,buf,DATA_MAX_LEN);

      buf[len] = ‘\0‘;

      printf("get data:%s\n",buf);

    }

  }

  return 0;

}


gcc -o epoll epoll.c
mkdir tmp
mkfifo tmp/1 tmp/2 tmp/3
./epoll tmp/1 tmp/2 tmp/3 &
echo aaa > tmp/1
echo bbb > tmp/2

 

課後作業:
編寫 inotify_epoll.c, 用它來監測tmp/目錄: 有檔案被建立/刪除, 有檔案可讀出資料
a. 當在tmp/下建立檔案時, 會立刻監測到,並且使用epoll監測該檔案
b. 當檔案有資料時,讀出資料
c. 當tmp/下檔案被刪除時,會立刻監測到,並且把它從epoll中移除不再監測

inotify_epoll.c
gcc -o inotify_epoll inotify_epoll.c
mkdir tmp
./inotify_epoll tmp/ &
mkfifo tmp/1 tmp/2 tmp/3
echo aaa > tmp/1
echo bbb > tmp/2
rm tmp/3

10.1、android輸入系統_必備Linux編程知識_inotify和epoll

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.