高级 IO

从多个文件描述符中读

  • 使用多个进程/线程,而后在每个进程/线程中使用阻塞 IO 读取,其中每个进程/线程的执行序列如:异步

while(read(fd,buf,buf_len)>0){/* 阻塞 IO */
    /* 处理读取获得的内容 */
}

  • 在一个进程/线程中使用非阻塞 IO,此时会形成大量的系统调用.async

while(true){/* fd1,fd2 均设置了 O_NONBLOCK 标志 */
    if(read(fd1,buf,buf_len)>0){
        /* 处理从 fd1 中读取的数据 */
    }
    if(read(fd2,buf,buf_len)>0){
        /* 处理从 fd2 中读取的数据 */
    }
}

  • 异步 IO.函数

    • 基本思想:进程告诉内核,当一个描述符已准备好能够进行 IO 时,用一个信号通知它.spa

    • 局限,通常状况下,内核只提供了一个异步 IO 信号,因此当进程收到一个异步 IO 信号时,只是知道了一个文件描述符能够进行 IO,但不知道具体是那个文件描述符.如:线程

void async_io_sigcatch(int,siginfo_t *siginfo,void *){/* 异步 IO 信号处理程序 */
    /* 仍须要以非阻塞模式读取,判断是那个文件描述符能够 IO */
   if(read(fd1,buf,buf_len)>0){ 
        /* 处理从 fd1 中读取的数据 */
    }
    if(read(fd2,buf,buf_len)>0){
        /* 处理从 fd2 中读取的数据 */
    }
}

  • IO 多路转接code

    • IO 多路转接函数: 首先在一个文件描述符上指定感兴趣的 IO 事件,而后调用 IO 多路转接函数,则 IO 多路转接函数会阻塞当前进程/线程直至文件描述符上感兴趣的 IO 事件之一发生.接口

    • Linux,能够执行 IO 多路转接的函数有 select(),poll(),epoll_wait()..
      进程

异步 IO

  • Linux 中,能够用做异步 IO 的信号有 SIGURG,SIGIO(Linux 下,SIGPOLL==SIGIO).事件

  • 使用 SIGURG,内存

    • 调用 fcntl(fd,F_SETOWN,进程 ID/进程组 ID),设置文件描述符的所属进程/所属进程组.

    • 此后,当 fd 上带外数据到达时,内核就会将 SIGURG 信号发送给指定的进程/进程组.

  • 使用 SIGIO/SIGPOLL 信号:

    • 调用 fcntl(fd,F_SETOWN,进程 ID/进程组 ID),设置文件描述符的所属进程/所属进程组.

    • 调用 fcntl(fd,F_SETFL,O_ASYNC|...),即调用 F_SETFL 设置 O_ASYNC 标志.

    • 此后当 fd 能够进行 IO 时,内核就会将 SIGIO/SIGPOLL 信号发送给指定的进程/进程组.

存储映射 IO

  • 存储映射 IO 使一个磁盘文件与进程地址空间上一段缓冲区相映射,因而当从内存区域中读取数据,就至关于读文件中的相应字节,将数据存入缓冲区,则相应字节就自动地写入文件中.

  • 页,是一个具备固定长度的内存块,长度能够经过 getpagesize()/sysconf(_SC_PAGESIZE) 获取.

/**
 * mmap [--len=LEN | -l LEN]
 * 	[--off=OFF | -o OFF]
 * 	[--read --write  -r -w ]
 * 	[ --private --shared -p -s]
 * 	[--close|-c]
 * 	[--verbose]
 * 	filename.
 * mmap() 系统调用的接口,mmap() 的函数原型: void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset).
 * --len|-l 指定了参数 length 的取值为 LEN,默认为文件的长度.
 * --off|-o 指定了参数 offset 的取值为 OFF,默认为 0.
 * --read|-r,--write|-w,指定了参数 prot 的取值为 PROT,默认为 PROT_READ|PROT_WRITE.
 * --shared|-s,--private|-p 指定了参数 flags 的取值为 FLAGS,默认为 MAP_SHARED.
 * --close | -c 指定了在调用 mmap() 以后关闭文件 fd,默认不关闭文件.
 * --verbose | -v 显示详细输出
 * 在程序运行中,能够输入:
 * show [--len=LEN|-l LEN] [--off=OFF|-o OFF]
 * 显示映射 [off,off+len) 范围内的内容.
 * --off | -o 指定了待显示范围的起始偏移,默认为 0.
 * --len | -l 指定了待显示范围的长度,默认为: length-OFF,length 为 mmap() 的第 2 个参数.
 *
 * modify [--off=OFF | -o OFF] STRING
 * 修改映射区的内容.
 * --off | -o 指定了被修改范围的起始偏移,默认为 0.
 * STRING 指定了修改内容,不包含了 '\0' .
 *
 * unmap [--off=OFF | -o OFF] [--len=LEN | -l LEN]
 * 解除映射
 * -o|--off 指定了被解除映射区域至关于 mmap_ret 的偏移,必须是 pagesize 的整数倍.
 * -l|--len 指定了被解除映射区的长度.
 *
 * protect [--off=OFF | -o OFF] [--len=LEN | -l LEN] [--read|-r][--write|-w]
 * 对指定的内存区域 [off,off+len) 设置保护.
 * --off|-o 默认值为 0.
 * --len|-l 默认值为 4096
 * --read|-r,--write|-w 指定了 prot,默认为 PROT_READ|PROT_WRITE.
 */
相关文章
相关标签/搜索