输入系统:epoll & inotify
一、epoll
作用:检测一个或多个文件的可读、可写等属性变化:
代码示例:
#include <sys/epoll.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h> #if 0
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t; #endif #define DATA_MAX_LEN 500 /* usage: epoll <file1> [file2] [file3] ... */ int add_to_epoll(int fd, int epollFd)
{
int result;
struct epoll_event eventItem;
memset(&eventItem, , 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)
{
epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, NULL);
} int main(int argc, char **argv)
{
int mEpollFd;
int i;
char buf[DATA_MAX_LEN]; // Maximum number of signalled FDs to handle at a time.
static const int EPOLL_MAX_EVENTS = ; // The array of pending epoll events and the index of the next event to be handled.
struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS]; if (argc < )
{
printf("Usage: %s <file1> [file2] [file3] ...\n", argv[]);
return -;
} /* epoll_create */
mEpollFd = epoll_create(); /* for each file:
* open it
* add it to epoll: epoll_ctl(...EPOLL_CTL_ADD...)
*/
for (i = ; i < argc; i++)
{
//int tmpFd = open(argv[i], O_RDONLY|O_NONBLOCK);
int tmpFd = open(argv[i], O_RDWR);
add_to_epoll(tmpFd, mEpollFd);
} /* epoll_wait */
while ()
{ int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, -);
for (i = ; i < pollResult; i++)
{
printf("Reason: 0x%x\n", mPendingEventItems[i].events);
int len = read(mPendingEventItems[i].data.fd, buf, DATA_MAX_LEN);
buf[len] = '\0';
printf("get data: %s\n", buf);
//sleep(3);
} } return ;
}
二、inotify
作用: 监控一个目录下文件的增加、删除事件:
代码示例:
#include <unistd.h>
#include <stdio.h>
#include <sys/inotify.h>
#include <string.h>
#include <errno.h> /*
*参考: frameworks\native\services\inputflinger\EventHub.cpp
*/ /*Usage: inotify <dir> */ int read_process_inotify_fd(int fd)
{
int res;
char event_buf[];
int event_size;
int event_pos = ;
struct inotify_event *event; /* read */
res = read(fd, event_buf, sizeof(event_buf)); if(res < (int)sizeof(*event)) {
if(errno == EINTR)
return ;
printf("could not get event, %s\n", strerror(errno));
return -;
} /* process
* 读到的数据是1个或多个inotify_event
* 它们的长度不一样
* 逐个处理
*/ while(res >= (int)sizeof(*event)) {
event = (struct inotify_event *)(event_buf + event_pos);
//printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
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 ;
} int main(int argc, char **argv)
{
int mINotifyFd;
int result; if (argc != )
{
printf("Usage: %s <dir>\n", argv[]);
return -;
} /* inotify_init */ mINotifyFd = inotify_init(); /* add watch */
result = inotify_add_watch(mINotifyFd, argv[], IN_DELETE | IN_CREATE); /* read */
while ()
{
read_process_inotify_fd(mINotifyFd);
} return ;
}
三、inotify和epoll的综合应用:
代码示例:
#include <sys/epoll.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/inotify.h>
#include <stdlib.h>
#include <errno.h> #define DATA_MAX_LEN 500
#define MAX_FILES 1000 static char *base_dir;
static char *epoll_files[MAX_FILES]; #if 0
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t; #endif /* usage: epoll <file1> [file2] [file3] ... */ int add_to_epoll(int fd, int epollFd)
{
int result;
struct epoll_event eventItem;
memset(&eventItem, , sizeof(eventItem));
eventItem.events = EPOLLIN;
eventItem.data.fd = fd;
result = epoll_ctl(epollFd, EPOLL_CTL_ADD, fd, &eventItem); //添加一个文件句柄到epoll监测列表
return result;
} void rm_from_epoll(int fd, int epollFd)
{
epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, NULL);
}
//通过文件名找到epoll监测列表中对应该文件的下标
int get_epoll_fd_for_name(char *name)
{
int i;
char name_to_find[];
sprintf(name_to_find, "%s/%s", base_dir, name); for (i = ; i < MAX_FILES; i++)
{
if (!epoll_files[i])
continue; if (!strcmp(epoll_files[i], name_to_find))
return i;
}
return -;
} /*
*参考: frameworks\native\services\inputflinger\EventHub.cpp
*/ /*Usage: inotify <dir> */ int read_process_inotify_fd(int mINotifyFd, int mEpollFd)
{
int res;
char event_buf[];
int event_size;
int event_pos = ;
struct inotify_event *event; /* read */
res = read(mINotifyFd, event_buf, sizeof(event_buf)); //返回值是一个或多个inotify_event总和大小 if(res < (int)sizeof(*event)) {
if(errno == EINTR)
return ;
printf("could not get event, %s\n", strerror(errno));
return -;
} /* process
* 读到的数据是1个或多个inotify_event
* 它们的长度不一样
* 逐个处理
*/ while(res >= (int)sizeof(*event)) {
event = (struct inotify_event *)(event_buf + event_pos);
//printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
if(event->len) {
if(event->mask & IN_CREATE) {
printf("create file: %s\n", event->name);
char *name = malloc();
sprintf(name, "%s/%s", base_dir, event->name);
int tmpFd = open(name, O_RDWR); printf("add to epoll: %s\n", name);
add_to_epoll(tmpFd, mEpollFd); epoll_files[tmpFd] = name; } else {
printf("delete file: %s\n", event->name);
int tmpFd = get_epoll_fd_for_name(event->name);
if (tmpFd >= )
{
printf("remove from epoll: %s/%s\n", base_dir, event->name);
rm_from_epoll(tmpFd, mEpollFd);
free(epoll_files[tmpFd]);
}
}
}
event_size = sizeof(*event) + event->len; //一个event大小=结构体大小+所含数据长度
res -= event_size;
event_pos += event_size;
}
return ;
} int main(int argc, char **argv)
{
int mEpollFd;
int i;
char buf[DATA_MAX_LEN];
int mINotifyFd;
int result; // Maximum number of signalled FDs to handle at a time.
static const int EPOLL_MAX_EVENTS = ; // The array of pending epoll events and the index of the next event to be handled.
struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS]; if (argc != )
{
printf("Usage: %s <tmp>\n", argv[]);
return -;
} base_dir = argv[]; /* epoll_create */
mEpollFd = epoll_create(); //创建epoll文件句柄 /* inotify_init */
mINotifyFd = inotify_init(); //创建inotify文件句柄,可用epoll监测 /* add watch */
result = inotify_add_watch(mINotifyFd, base_dir, IN_DELETE | IN_CREATE); //设置监测inotify文件句柄 add_to_epoll(mINotifyFd, mEpollFd); //使用epoll监测inotify文件句柄 /* epoll_wait */
while ()
{
int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, -); //当文件有数据可读时返回
for (i = ; i < pollResult; i++)
{
if (mPendingEventItems[i].data.fd == mINotifyFd) //当监测到的文件句柄为mINodifyFd(目录)时说明有文件创建/删除
{
read_process_inotify_fd(mINotifyFd, mEpollFd); //根据event->name 添加/移除 对该文件的监测
}
else
{
printf("Reason: 0x%x\n", mPendingEventItems[i].events);
int len = read(mPendingEventItems[i].data.fd, buf, DATA_MAX_LEN);
buf[len] = '\0';
printf("get data: %s\n", buf);
//sleep(3);
}
} } return ;
}
输入系统:epoll & inotify的更多相关文章
- Android系统--输入系统(一)必备的Linux知识_inotify和epoll
Android系统--输入系统(一)必备的Linux知识_inotify和epoll 引入 1. 笔记本电脑插入外接键盘,两个键盘都可以使用 a. 键盘即插即用--如何检测键盘的接入和拔出 hotpl ...
- 10.1、android输入系统_必备Linux编程知识_inotify和epoll
1. inotify和epoll 怎么监测键盘接入与拔出? (1)hotplug机制:内核发现键盘接入/拔出==>启动hotplug进程==>发消息给输入系统 (2)inotify机制:输 ...
- [Android] 输入系统(一)
Android输入系统是人与机器交互最主要的手段.我们通过按键或者触碰屏幕,会先经由linux产生中断,进行统一的处理过后,转换成Android能识别的事件信息,然后Android的输入系统去获取事件 ...
- Android系统--输入系统(八)Reader线程_使用EventHub读取事件
Android系统--输入系统(八)Reader线程_使用EventHub读取事件 1. Reader线程工作流程 获得事件 size_t count = mEventHub->getEvent ...
- Android系统--输入系统(二)必备Linux知识_实现inotify_epoll.c
Android系统--输入系统(二)必备Linux知识_实现inotify_epoll.c 课后作业 1. 编写 inotify_epoll.c, 用它来监测tmp/目录: 有文件被创建/删除, 有文 ...
- 《深入理解Android 卷III》第五章 深入理解Android输入系统
<深入理解Android 卷III>即将公布.作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白.即Android Framework中和UI相关的部分. ...
- 10.5 android输入系统_Reader线程_使用EventHub读取事件和核心类及配置文件_实验_分析
4. Reader线程_使用EventHub读取事件 使用inotify监测/dev/input下文件的创建和删除 使用epoll监测有无数据上报 细节: a.fd1 = inotify_init(& ...
- Android系统--输入系统(十一)Reader线程_简单处理
Android系统--输入系统(十一)Reader线程_简单处理 1. 引入 Reader线程主要负责三件事情 获得输入事件 简单处理 上传给Dispatch线程 InputReader.cpp vo ...
- Android系统--输入系统(十六)APP跟输入系统建立联系_InputChannel和Connection
Android系统--输入系统(十六)APP跟输入系统建立联系_InputChannel和Connection 0. 核心:socketpair机制 1. 回顾Dispatch处理过程: 1.1 放入 ...
- 10.9 android输入系统_APP跟输入系统建立联系和Dispatcher线程_分发dispatch
12. 输入系统_APP跟输入系统建立联系_InputChannel和Connection核心: socketpair // 第9课第3节_输入系统_必备Linux编程知识_任意进程双向通信(scok ...
随机推荐
- POP3、SMTP和IMAP介绍和设置
什么是POP3.SMTP和IMAP? 参照:http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html 用于 Outlook 的 POP 和 IMAP 电 ...
- mo系统常用语句
mo系统常用语句 一.总结 一句话总结: 1.语言:双语设置(繁体,英语)语句? {:chooseLanguage("確定要刪除么","Are you sure you ...
- 昂达 v891 v1 终于 删除 windows 分区 并且恢复了容量。
参考了很多文章(最后列出重要的),却始终失败. 途中因为乱改分区表,竟然fastboot 都进不去了,当时真是欲哭无泪. 总结关键点: 1) partition.tbl不能把硬盘剩余空间全给data分 ...
- 雷林鹏分享:C# 基本语法
C# 基本语法 C# 是一种面向对象的编程语言.在面向对象的程序设计方法中,程序由各种相互交互的对象组成.相同种类的对象通常具有相同的类型,或者说,是在相同的 class 中. 例如,以 Rectan ...
- public class feign.RetryableException feign.RetryableException: Connection refused (Connection refused) executing POST http://common-wx/wx/auth/client/token/v1
一.异常出现的场景 Spring Cloud内部两个服务A和B,A调用B时,抛出该异常.提示连接拒绝 public class feign.RetryableException feign.Retry ...
- GreenDao使用解析
GreenDao是一个轻量级的数据库框架,相比Xutils 等他的速度和效率会更快更好 这里展示GreenDao 的使用方法 ①建立 compile 'org.greenrobot:greendao: ...
- es的分词器analyzer
analyzer 分词器使用的两个情形: 1,Index time analysis. 创建或者更新文档时,会对文档进行分词2,Search time analysis. 查询时,对查询语句 ...
- 2 爬虫 requests模块
requests模块 Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests它会比urllib更加方便,reques ...
- Python操作excel的几种方式--xlrd、xlwt、openpyxl
openpyxl xlrd xlwt 在处理excel数据时发现了xlwt的局限性–不能写入超过65535行.256列的数据(因为它只支持Excel 2003及之前的版本,在这些版本的Excel中 ...
- Android VideoView播放网络视频简介(转)
最近项目中用到了很多视频播放的地方,不管是聊天发送的视频消息,还是类似内涵段子的视频列表,都会涉及这些知识,不过网上的知识都很零散,一会找缓存方法,一会找预览图片的方法,一会找视频动态修改尺寸的方法, ...