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

来源:互联网 发布:camtasia studio7软件 编辑:程序博客网 时间:2024/06/04 18:40

一、高级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(),

缺点:

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

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

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