存档

  • Linux 异步 IO 之 eventfd

    经过 3 个月的休(tou)息(lan),是时候写点东西了……

    eventfd

    较新版本的 Linux 内核(2.6.22 之后)提供了一个新的系统调用 eventfd() 来实现事件通知(参考资料 [1]):

    #include <sys/eventfd.h>
    
    int eventfd(unsigned int initval, int flags);
    

    函数返回一个可用于 read()/write()/epoll()/close() 的 fd,fd 包含一个由内核维护的 8 字节的无符号整数,初始值由第一个参数 initval 制定。write() 的 buffer 大小都限定为 8 字节,如果 buffer 大小不等于 8 字节则会返回错误,如果提供给 read() 的大小小于 8 …

    阅读全文…

    2015年10月31日 | 归档: api | 标签:
  • Linux 异步 IO 之 Native AIO

    Linux Native AIO

    来看看 Linux 提供的 AIO 系统调用(自行封装的头文件 native_aio.h):

    #ifndef __NATIVE_AIO_H__
    #define __NATIVE_AIO_H__
    
    #define _GNU_SOURCE
    
    #include <unistd.h>
    #include <sys/syscall.h>
    #include <sys/time.h>
    #include <linux/aio_abi.h>
    
    static inline int io_setup(unsigned nr_events, aio_context_t* ctx_idp)
    {
        return syscall(__NR_io_setup, nr_events, ctx_idp);
    }
    
    static inline int io_destroy(aio_context_t 

    阅读全文…

    2015年6月30日 | 归档: api | 标签:
  • Linux 异步 IO 之 POSIX AIO

    先来看一个简单的读写文件程序,程序读取源文件,然后把内容打印到屏幕上:

    #include <unistd.h>
    #include <fcntl.h>
    
    #define BUFSIZE 4096
    
    int main(void)
    {
        int fd, nbytes;
        char buf[BUFSIZE];
    
        fd = open(__FILE__, O_RDONLY);
        while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
            write(1, buf, nbytes);
    
        close(fd);
        return 0;
    }
    

    在这个例子中的 read()/write() 都是同步阻塞 IO,即如果没有数据可读或写入未完成时当前线程会一直等待,直到读写操作完成或出错才会返回。

    同步 …

    阅读全文…

    2015年5月31日 | 归档: api | 标签:
  • Linux 异步 IO 之 epoll

    epoll 是 Linux 内核在 2.5 引入的一个 I/O 事件通知机制,用来取代旧的 select(2) 和 poll(2)。

    select() 的工作模式

    从通知机制上说,select() 的方式和 epoll 的方式类似,都是阻塞在某个函数上,如果有指定的 I/O 事件发生的话函数就会返回。这样的通知机制的好处在于,在没有事件发生的时候系统可以去干别的事情。不过 select() 只告诉你有事件发生了,但是没有说清楚是哪些 fd 触发了事件通知,你需要去遍历所有的 fd 来找出哪些真正需要处理。select() 的函数原型如下:

    int select(int nfds, fd_set *readfds, fd_set *writefds,
               fd_set *exceptfds, struct timeval *timeout);
    

    fd_set 是一个 …

    阅读全文…

    2014年10月26日 | 归档: api | 标签: ,
  • 使用 inotify 监控目录和文件的状态

    概述

    很多时候程序需要对文件状态进行监控,例如在命令行中删掉一个文件,图形界面中的文件管理器也要把这个文件去掉(如果文件管理器正在显示被删除文件所在的目录);如果试图用 vim 保存一个文件,而该文件在修改的时候被其它程序修改过,那么 vim 会给出警告说文件已经发生改变。如果需要对文件状态进行实时监控,一个方法是保存文件的状态,然后不停地扫描目录或文件,如果和上一次保存的状态不一致则发出信号,但是这样的做法效率很低。最好的做法是能够向系统注册一个回调函数,当我们需要监控的目录或文件发生改变时调用回调函数,这样程序就能马上得到通知。

    根据参考资料 [1],inotify 之前的文件状态监控机制是 dnotify。dnotify 中的“d”指的是目录,只能监控目录事件的变化,即在该目录下的创建/删除文件引起的事件,但是却不能监控文件本身状态的改变(如读写/访问文件),如果需要实现这样的功能需要应用程序自己比较文件状态。

    在 2.6.13 的时候引入的 inotify 提供了比 dnotify 更强大的功能,除了目录还可以对文件状态进行监控。并且它不像 dnotify,每监控一个目录/文件都需要打开一个文件描述符,因此不会影响移动介质的 unmount。从接口形式和功能上看,inotify 和 epoll 很像,只是两者监控的事件类型不一样。

    09 年出现了 fanotify(参考资料 [2]),据说是 inotify 的下一代,不过目前来看功能还不如 inotify。

    对目录的监控

    作为 inotify 的第一个示例,程序会在 /tmp/abc 被创建/删除/移动时打印相应的信息:

    #include <stdio.h>
    #include <string.h>
    

    阅读全文…

    2014年2月27日 | 归档: api | 标签: ,
‘api’ 分类的存档