一、inotify 和 epoll

1.Android不使用hotplug机制,使用的是inotify机制。inotify监听的是/dev/input目录。

2.使用inotify来监听文件的创建与删除,使用epoll来监听设备文件句柄的变化,包括inotify的fd。

3.epoll支持管道,FIFO,套接字,POSIX消息队列,终端,设备等,但是就是不支持普通文件或目录的fd。
测试验证,使用fifo测试epoll是可以的,但是使用普通文件来测试epoll的并发监听是不行的。

3.参考代码: frameworks\native\services\inputflinger\EventHub.cpp

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

4.测试遇到问题:使用O_RDONLY|O_NONBLOCK打开的FIFO让epoll去监听,echo一个数据到fifo中后,epoll_wait()一直无法阻塞住。
tmpFd = open(argv[i], O_RDONLY|O_NONBLOCK);
解答: 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, 描述符被挂断(这个可以从epoll_event结构中看到EPPLLHUP码))
b.
如果reader以O_RDWR打开FIFO文件
当writer写入数据时, epoll_wait会立刻返回;
当writer关闭FIFO之后, reader再次调用epoll_wait, 它并不会立刻返回, 而是继续等待有数据

5.使用分号隔开可以实现在命令行中输入多条语句:eg:# echo 1 > tmp/5; echo 2 > tmp/2

6.试验Demo

inotify.c

#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[512];
    int event_size;
    int event_pos = 0;
    struct inotify_event *event;
    
    /* block read */    
    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;
    }

    /* process
     * ¶Áµ½µÄÊý¾ÝÊÇ1¸ö»ò¶à¸öinotify_event
     * ËüÃǵij¤¶È²»Ò»Ñù
     * Öð¸ö´¦Àí
     */

    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; // buf[0] with no length
        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;
    }

    /* inotify_init */

    mINotifyFd = inotify_init();

    /* add watch */
    result = inotify_add_watch(mINotifyFd, argv[1], IN_DELETE | IN_CREATE);

    /* read */
    while (1)
    {
        read_process_inotify_fd(mINotifyFd);
    }

    return 0;
}
View Code

相关文章:

  • 2021-11-15
  • 2021-05-30
  • 2021-10-24
  • 2022-12-23
  • 2021-11-28
  • 2022-12-23
  • 2022-03-05
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-27
  • 2021-08-10
  • 2021-11-17
相关资源
相似解决方案