• UNIX环境高级编程--高级I/O(三)


    一、高级I/O

    包括非阻塞I/O、记录锁、系统V流机制、I/O多路回转(select和poll函数)、readv和writev函数以及存储映射I/O(mmap),这些都是高级I/O.

       其实在上面讲述的这三类I/O,首先讲述了linux下的基本I/O系统调用,这些调用不仅仅是文件I/O的基础,也是linux下所有通信方式的基础;接着讲述了基础I/O系统调用之上经常需要在用户空间做缓冲,学习了一个用户空间缓冲的解决方案,既C的标准I/O库,这一章讲述了Linux提供的更多高级I/O系统调用。


    标准I/O库处理很多细节,例如缓冲区分配,以优化长度执行I/O等。

    标准I/O库提供缓冲的目的是尽可能减少使用read和write调用的次数。

    标准I/O提供了三种类型的缓冲:

    1)全缓冲。这种情况下,在填满标准I/O缓冲区后才进行实际I/O操作。对于驻留在磁盘上的文件通常是由标准I/O库实施全缓冲的。在一个流上执行第一次I/O操作时,相关标准I/O函数通常调用malloc获得需使用的缓冲区。

    2)行缓冲。在这种情况下,当在输入和输出中遇到换行符是,标准I/O库执行I/O操作。这允许我们一次输出一个字符(标准I/Ofputc函数),但只有在写了一行之后才进行实际I/O操作。当流涉及一个终端时(例如标准输入和标准输出),通常使用行缓冲。

    3)不带缓冲。标准I/O库不对字符进行缓冲存储。例如,如果用标准I/O函数fputs写15个字符到不带缓冲的流中,则该函数很可能用上面讲述的write系统调用函数将这些字符立即写至关联的打开的文件上。


    #include <stdio.h>

    void setbuf(FILE *restrict fp,char *restrict buf);

    int  setvbuf(FILE *restrict fp,char *restrict buf,int mode,size_t size); // 若成功则返回0,出错则返回非0值

         

    mmap()函数的使用

          #include <sys/mman.h>

      void * mmap(void *addr,size_t len,int port,int flags,int fd,off_t offset);

    使用read()、write()系统调用需要从用户缓冲区进行数据读写,而使用映射文件进行操作可以避免多余的数据拷贝。

    除了潜在的页错误,读写映射文件不会带来系统调用和上下文切换的开销。就像直接操作内存一样简单。

    当多个进程映射同一个对象到内存中,数据在进程间共享,只读和写共享的映射在全体中都是共享的;私有可写的尚未进行写时拷贝的页是共享的。

    在映射对象中搜索只需要一般的指针操作。而不必使用lseek(),

    缺点:

        映射区域的大小通常是也大小的整数倍。

        存储映射区域必须在进程地址空间内。

        创建和维护映射以及相关的内核数据结构有一定的开销。

  • 相关阅读:
    IDEA 代码统计插件使用
    四种遍历ConcurrentHashMap的方式
    Java中多线程并发体系知识点汇总
    程序员高效工具列表
    js数组与字符串的相互转换方法
    ajax使用json数据格式--无效的 JSON 基元
    for和$.each 的记录
    表单提交模型记录
    /Date(1512551901709+0800)/转换
    jsonp的使用记录
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3339567.html
Copyright © 2020-2023  润新知