博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UNIX环境高级编程--高级I/O(三)
阅读量:5334 次
发布时间:2019-06-15

本文共 1266 字,大约阅读时间需要 4 分钟。

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

缺点:

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

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

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

 

转载于:https://www.cnblogs.com/suncoolcat/p/3339567.html

你可能感兴趣的文章
bzoj1005: [HNOI2008]明明的烦恼(prufer+高精度)
查看>>
poj3683 Priest John's Busiest Day
查看>>
来自java文档 java.net包
查看>>
js call理解
查看>>
lr参数化取值规则总结
查看>>
Unsupported major.minor version 51.0
查看>>
ios学习:文件简单读写
查看>>
最近有些堕落了~
查看>>
Entity Framework 6 编译出错的问题(VS2012)
查看>>
Java多线程-新特性-线程池
查看>>
javascript中onSubmit="return xxx()"的问题
查看>>
Fiddler抓包【1】_介绍及界面概述
查看>>
OpenOCD初始化脚本(u-boot)
查看>>
python数字图像处理(10):图像简单滤波
查看>>
phonegap ios默认启动页
查看>>
第四章 栈与队列3 (堆栈的应用)
查看>>
object.key和object[key]
查看>>
网络IPC:套接字之带外数据
查看>>
Vue – 基础学习(2):组件间 通信及参数传递
查看>>
平台调用数据类型
查看>>