一、分散聚离(向量) I/O

[a] readv / writev

#include <sys/uio.h>
ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
/*成功返回已操作的字节数量,出错返回 -1*/
struct iovec {
void *iov_base; //缓冲区地址
size_t len;
  • 用于针对多个不连续缓冲区同时写入写出的原子操作,减少了系统调用次数,通常提供比线性 I/O 更高的效率与性能
  • 参数 iov 是指向 iovec 结构体的数组的指针,当其元素数量 <=8 时,系统通常会在栈上分配空间以优化性能
  • 按数组元素順序依次读写

[b] 样例

#include <sys/uio.h>
#include <fcntl.h>
#include <stdio.h>
#define N0 10
#define N1 20
#define N2 30 int
main(void)
{
char *file = "/var/log/messages";
int fd, i;
char test0[N0], test1[N1], test2[N2];
struct iovec iov[]; fd = open(file, O_RDONLY);
if (- == fd)
{
perror("open");
} iov[].iov_base = test0;
iov[].iov_len = N0;
iov[].iov_base = test1;
iov[].iov_len = N1;
iov[].iov_base = test2;
iov[].iov_len = N2; i = readv(fd, iov, );
if (- == i)
{
perror("readv");
}
((char *)(iov[].iov_base))[N0 - ] = '\n';
((char *)(iov[].iov_base))[N1 - ] = '\n';
((char *)(iov[].iov_base))[N2 - ] = '\n';
i = writev(, iov, );
if (- == i)
{
perror("writev");
}
}
fh@Server ~/APUE$ ./a.out
Dec
: Server newsys
og[]: logfile turned over  

二、存储影射(内存影射)

[a] mmap / munmap

#include <sys/mman.h>
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) //成功返回分配到的内存位置(指针),出错返回 MAP_FAILED
int munmap(void *addr, size_t len) //成功返回 0,出錯返回 -1
  • mmap:

    • addr 通常设置为 0,表示由系统自动分配内存
    • len 指定要 map 的内存区域字节长度
    • prot 指定影射内存区的权限,由 PROT_READ / PROT_WRITE / PROT_EXEC 按位 OR 賦值,不能与 open 调用的权限位或其它系统权限策略冲突
    • flags 常用选项:MAP_SHARED / MAP_PRIVATE,前者对影射内存区的更改会写入文件,后者采用写时复制(COW)创建内存副本,不修改源文件
    • fd 是与将要 map 的目标文件相关联的文件描述符
    • offset 指定从目标文件 map 的起始位置(距离文件开头的偏移量),如指定为 100,意为从第 100 字节开始 map 长度为 len 字节的内容到 mmap 函数返回的指针所指向的内存区
  • mmap 函数分配出的内存都是以页为单位对齐的,通常适用于分配较大的内存;malloc 函数的分配方法通常是小内存(<128KB)在堆上分配,大内存使用内存影射
  • 运行时获取页大小:sysconf(_SC_PAGESIZE)
  • 内存影射优点:
    • 直接操作内存,不使用缓冲区,避免了多余的数据复制
    • 不调用 read、write 等系统调用,无上下文切换的开销
    • 多个进程 map 同一文件的同一区段的时候,数据会在所有进程间共享
    • 文件偏移只需要移动指针,无须再调用 lseek
  • 内存影射的缺点:
    • 映射区域的大小总是页大小的整数倍,对于小文件会造成内存浪费
    • 创建和维护映射及相关内核数据结构会有一定的开销,但相对于其节省的开销,是可以忽略的

[b] msync / mprotect

#include <sys/mman.h>
int msync(void *addr, size_t len, int flags) //成功返回 0,出错返回 -1
int mprotect(const void *addr, size_t len, int prot) //同上 
  • msync 相当于专门用于内存影射的 fsync,flags 可用选项有 MS_SYNC / MS_ASYNC,前者只有当数据真正已写回磁盘,msync 函数才返回,后者立即返回,数据何时真正写回磁盘,由系统调度
  • mprotect 用于更改指定内存区域的权限,通常是先前用 mmap 分配的区域,但 Linux 可以用于更改任意用户空间可用的内存区域

三、POSIX I/O 提示

#include <fcntl.h>
int posix_fadvise(int fd, off_t offset, off_t len, int advice) //成功返回 0,出错不设置 errno 
    The behavior is specified by the advice parameter and may be one of:

     POSIX_FADV_NORMAL      Tells the system to revert to the default data
access behavior. POSIX_FADV_RANDOM Is a hint that file data will be accessed
randomly, and prefetching is likely not
advantageous. POSIX_FADV_SEQUENTIAL Tells the system that file data will be accessed
sequentially. This currently does nothing as the
default behavior uses heuristics to detect
sequential behavior. POSIX_FADV_WILLNEED Tells the system that the specified data will be
accessed in the near future. The system may
initiate an asynchronous read of the data if it is
not already present in memory. POSIX_FADV_DONTNEED Tells the system that the specified data will not
be accessed in the near future. The system may
decrease the in-memory priority of clean data
within the specified range and future access to
this data may require a read operation. POSIX_FADV_NOREUSE Tells the system that the specified data will only
be accessed once and then not reused. The system
may decrease the in-memory priority of data once
it has been read or written. Future access to
this data may require a read operation. 
  • 指定恰当的预读策略,可大幅提升普通文件 I/O 性能
  • offset 为 0 时,提示从文件开头预读,当 offset 与 len 同时为 0 时,表示整个文件

[12]APUE:高级 I/O的更多相关文章

  1. 12. javacript高级程序设计-DOM2和DOM3

    1. DOM2和DOM3 DOM2级规范定义了一些模块,用于增强DOM1级.“DOM2级核心”为不同的DOM类型引入了一些与XML命名空间有关的方法,这些变化只在使用XML或者XHTML,对于HTML ...

  2. 12.mysql高级查询

    1. mysql 支持三种类型的连接查询: on 后面跟的是关联条件 内连接查询 select s.name,c.name from students as s inner join classes ...

  3. 12.创建高级联结---SQL

    一.使用表别名 SQL除了可以对列名和计算字段使用别名,还允许给表名起别名.这样做有两个主要理由: 缩短SQL语句: 允许在一条SELECT语句中多次使用相同的表. SELECT cust_name, ...

  4. linQ学习笔记之三高级语句

    linq语句查询执行的时机 第一步获取数据源 int [] obejct = new int[]{1,2,3,4,5,6,7,8,9} 第二步定义查询 var even = numbers.where ...

  5. 软件测试人员必备Linux命令(初、中、高级)

    有些技能可以事半功倍,有些命运掌握在我们手中.熟练的掌握和使用这些命令可以提高工作效率,并且结合这些命令对测试过程中遇到的问题进行一些初步的定位. 1 目录与文件操作1.1 ls(初级)使用权限:所有 ...

  6. 第32章 TIM—高级定时器—零死角玩转STM32-F429系列

    第32章     TIM—高级定时器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  7. 高级程序员与CTO技术总监首席架构师

    一.高级程序员 如果你是一个刚刚创业的公司,公司没有专职产品经理和项目经理,你就是公司的产品经理,你如果对你现在的开发员能力不满,那么你只需要的是一个高级程序员. 你定义功能.你做计划推进和管理,他可 ...

  8. SQL 必知必会

    本文介绍基本的 SQL 语句,包括查询.过滤.排序.分组.联结.视图.插入数据.创建操纵表等.入门系列,不足颇多,望诸君指点. 注意本文某些例子只能在特定的DBMS中实现(有的已标明,有的未标明),不 ...

  9. [转]CTO、技术总监、首席架构师的区别

    经常有创业公司老板来拜访我,常常会拜托给我一句话:帮我找一个CTO. 我解释的多了,所以想把这个写下来,看看你到底需要的应该是啥. 一.高级程序员 如果你是一个刚刚创业的公司,公司没有专职产品经理和项 ...

随机推荐

  1. [HTML]JS全屏代码

    video全屏参考:https://www.thecssninja.com/javascript/fullscreen <!doctype html> <html> <h ...

  2. python types模块

    types模块成员: ['BooleanType', 'BufferType', 'BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', 'C ...

  3. Web前端安全问题

    1.XXS跨站脚本攻击(Cross Site Scripting) 1)通过<script> 举个例子:通过QQ群,或者通过群发垃圾邮件,来让其他人点击这个地址: book.com/sea ...

  4. nginx 自动忽略request中header name包含下划线参数的解决方法

    使用nginx过程中遇到了个问题,就是request中的header name中如果包含下划线会自动忽略掉,导致服务器接收不到该字段的内容,以下为解决方法: nginx默认request的header ...

  5. Linux和windows之间通过scp复制文件

    Windows是不支持ssh协议的 需要安装WinSSHD 安装以及设置过程如下: BvSshServer(原名winsshd)官方下载页在这里:https://www.bitvise.com/dow ...

  6. Xamarin Android自学和实践步骤

    一.入门(已完成) 1.学习Xamarin Android项目的基本结构 2.学习界面布局的基本方式 3.学习基本编码规则 4.学习页面跳转和传值 5.学习对话框和提示信息显示方法 6.学习使用系统剪 ...

  7. Net分布式系统之四:RabbitMQ消息队列应用

    消息通信组件Net分布式系统的核心中间件之一,应用与系统高并发,各个组件之间解耦的依赖的场景.本框架采用消息队列中间件主要应用于两方面:一是解决部分高并发的业务处理:二是通过消息队列传输系统日志.目前 ...

  8. c#winform窗体嵌入

    最近开发项目,错误的理解了需求,自己做了个窗体的嵌套,虽然是错误的理解了,但是功能还是实现了,做下标记,需要时可以拿来看看. 新建两个窗体Form1和Form2,现在需要将Form2显示到Form1里 ...

  9. 正确理解javascript当中的面向对象

    认识面向对象: 为了说明 JavaScript 是一门彻底的面向对象的语言,首先有必要从面向对象的概念着手 , 探讨一下面向对象中的几个概念: 1.万物皆为空:万物皆对象 2.对象具有封装和继承特性 ...

  10. IOS系列swift语言之课时七

    这下需要掌握的就是类型转换,类的构造器,判断类型,异常,异常的处理,defer,范型,约束加速刷代码 import Foundation /* 类型转换 1.利用类的构造器进行转换 2.系统可能提供一 ...