使用多个进程/线程,而后在每个进程/线程中使用阻塞 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()..
进程
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 使一个磁盘文件与进程地址空间上一段缓冲区相映射,因而当从内存区域中读取数据,就至关于读文件中的相应字节,将数据存入缓冲区,则相应字节就自动地写入文件中.
页,是一个具备固定长度的内存块,长度能够经过 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. */