不带缓存的I/O和标准(带缓存的)I/O
首先,先稍微了解系统调用的概念:
系统调用,英文名system call,每个操作系统都在内核里有一些内建的函数库,这些函数可以用来完成一些系统系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序,及别的功能,这些函数集合起来就叫做程序接口或应用编程接口(Application Programming Interface,API),我们要在这个系统上编写各种应用程序,就是通过这个API接口来调用系统内核里面的函数。如果没有系统调用,那么应用程序就失去内核的支持。
现在,再聊不带缓存的I/O操作:
linix对IO文件的操作分为不带缓存的IO操作和标准IO操作(即带缓存),刚开始,要明确以下几点:
1:不带缓存,不是直接对磁盘文件进行读取操作,像read()和write()函数,它们都属于系统调用,只不过在用户层没有缓存,所以叫做无缓存IO,但对于内核来说,还是进行了缓存,只是用户层看不到罢了。如果这一点看不懂,请看第二点;
2:带不带缓存是相对来说的,如果你要写入数据到文件上时(就是写入磁盘上),内核先将数据写入到内核中所设的缓冲储存器,假如这个缓冲储存器的长度是100个字节,你调用系统函:
ssize_t write (int fd,const void * buf,size_t count);
写操作时,设每次写入长度count=10个字节,那么你几要调用10次这个函数才能把这个缓冲区写满,此时数据还是在缓冲区,并没有写入到磁盘,缓冲区满时才进行实际上的IO操作,把数据写入到磁盘上,所以上面说的“不带缓存不是就没有缓存直写进磁盘”就是这个意思。
那么,既然不带缓存的操作实际在内核是有缓存器的,那带缓存的IO操作又是怎么回事呢?
带缓存IO也叫标准IO,符合ANSI C 的标准IO处理,不依赖系统内核,所以移植性强,我们使用标准IO操作很多时候是为了减少对read()和write()的系统调用次数,带缓存IO其实就是在用户层再建立一个缓存区,这个缓存区的分配和优化长度等细节都是标准IO库代你处理好了,不用去操心,还是用上面那个例子说明这个操作过程:
上面说要写数据到文件上,内核缓存(注意这个不是用户层缓存区)区长度是100字节,我们调用不带缓存的IO函数write()就要调用10次,这样系统效率低,现在我们在用户层建立另一个缓存区(用户层缓存区或者叫流缓存),假设流缓存的长度是50字节,我们用标准C库函数的fwrite()将数据写入到这个流缓存区里面,流缓存区满50字节后在进入内核缓存区,此时再调用系统函数write()将数据写入到文件(实质是磁盘)上,看到这里,你用该明白一点,标准IO操作fwrite()最后还是要掉用无缓存IO操作write,这里进行了两次调用fwrite()写100字节也就是进行两次系统调用write()。
如果看到这里还没有一点眉目的话,那就比较麻烦了,希望下面两条总结能够帮上忙:
无缓存IO操作数据流向路径:数据——内核缓存区——磁盘
标准IO操作数据流向路径:数据——流缓存区——内核缓存区——磁盘
这两天在看UNIX环境高级编程,再来点基础的(发现自己是越来越弱了
)
首先说说不带缓存的I/O,UNIX的文件I/O read、write是不带缓存的。不带缓存是指每个read、write都调用内核的一个系统调用,它们是POSIX.1的组成部分。二者的原型为:
ssize_t read( int filedes, void* buf, size_t nbytes ); // 若成功返回读到的字节数
ssize_t write( int filedes, const void* buf, size_t nbytes ); // 若成功返回已写的字节数
注意,上面的buf不是指read、write带缓存,而是当read时用来存放读出的字节,write时存放待写的字节。对于read,nbytes表示每次最多读的字节数。但这个块的大小将影响I/O的效率,其值和具体系统有关。
补充一下,不带缓存的I/O对文件描述符操作,下面带缓存的I/O是针对流的。
标准I/O库就是带缓存的I/O,它由ANSI C标准说明。当然,标准I/O最终都会调用上面的I/O例程。标准I/O库代替用户处理很多细节,比如缓存分配、以优化长度执行I/O等。
标准I/O提供缓存的目的就是减少调用read和write的次数,它对每个I/O流自动进行缓存管理(标准I/O函数通常调用malloc来分配缓存)。它提供了三种类型的缓存:
1) 全缓存。当填满标准I/O缓存后才执行I/O操作。磁盘上的文件通常是全缓存的。
2) 行缓存。当输入输出遇到新行符或缓存满时,才由标准I/O库执行实际I/O操作。stdin、stdout通常是行缓存的。
3) 无缓存。相当于read、write了。stderr通常是无缓存的,因为它必须尽快输出。
一般而言,由系统选择缓存的长度,并自动分配。标准I/O库在关闭流的时候自动释放缓存。
在标准I / O库中,一个效率不高的不足之处是需要复制的数据量。当使用每次一行函数fgets和fputs时,通常需要复制两次数据:一次是在内核和标准I / O缓存之间(当调用read和write时),第二次是在标准I / O缓存(通常系统分配和管理)和用户程序中的行缓存(fgets的参数就需要一个用户行缓存指针)之间。
不管上面讲的到底懂没懂,记住一点:
使用标准I / O例程的一个优点是无需考虑缓存及最佳I / O长度的选择,并且它并不比直接调用read、write慢多少。
不带缓存的I/O和标准(带缓存的)I/O的更多相关文章
- nginx反向代理+缓存开启+url重写+负载均衡(带健康探测)的部署记录
在日常运维工作中,运维人员会时常使用到nginx的反向代理,负载均衡以及缓存等功能来优化web服务性能. 废话不多说,下面对测试环境下的nginx反向代理+缓存开启+url重写+负载均衡(带健康探测) ...
- 浅谈无缓存I/O操作和标准I/O文件操作差别
首先,先略微了解系统调用的概念: 系统调用,英文名system call,每一个操作系统都在内核里有一些内建的函数库,这些函数能够用来完毕一些系统系统调用把应用程序的请求传给内核,调用对 ...
- 无缓存I/O操作和标准I/O文件操作区别
本文转载于:http://www.360doc.com/content/11/0521/11/5455634_118306098.shtml 首先,先稍微了解系统调用的概念: 系统调用,英 ...
- ASP.NET缓存全解析7:第三方分布式缓存解决方案 Memcached和Cacheman 转自网络原文作者李天平
Memcached — 分布式缓存系统 1.Memcached是什么? Memcached是高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度.Memcached通过在内 ...
- ASP.NET缓存全解析3:页面局部缓存 转自网络原文作者李天平
有时缓存整个页面是不现实的,因为页的某些部分可能在每次请求时都需要变化.在这些情况下,只能缓存页的一部分.顾名思义,页面部分缓存是将页面部分内容保存在内存中以便响应用户请求,而页面其他部分内容则为动态 ...
- 缓存(之一) 使用Apache Httpd实现http缓存
http://www.tuicool.com/articles/EFfeu2 HTTP性能的问题与方案 一个最终用户访问一个网页,从浏览器发出请求,到接受请求,时间大体上消耗在了以下几个部分: 建立t ...
- WEB 应用缓存解析以及使用 Redis 实现分布式缓存
什么是缓存? 缓存就是数据交换的缓冲区,用于临时存储数据(使用频繁的数据).当用户请求数据时,首先在缓存中寻找,如果找到了则直接返回.如果找不到,则去数据库中查找.缓存的本质就是用空间换时间,牺牲数据 ...
- SpringBoot缓存管理(三) 自定义Redis缓存序列化机制
前言 在上一篇文章中,我们完成了SpringBoot整合Redis进行数据缓存管理的工作,但缓存管理的实体类数据使用的是JDK序列化方式(如下图所示),不便于使用可视化管理工具进行查看和管理. 接下来 ...
- ThinkPHP中的动态缓存(S方法)和快速缓存(F方法)
系统默认的缓存方式是采用File方式缓存,我们可以在项目配置文件里面定义其他的缓存方式,例如,修改默认的缓存方式为Xcache(当然,你的环境需要支持Xcache) 对于File方式缓存下的缓存 ...
随机推荐
- ScrollView图片分页显示-简单
用到的控件: 1>UIScrollView:宽度和图片的宽度一样,因为分页的代码就一句 // 设置分页,这个分页的原理实际上是按照ScrollView的宽进行分页的,这里的图片的宽由于和Scro ...
- 【String to Integer (atoi) 】cpp
题目: Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input ca ...
- 2. ProGit-Git基础
(1) 取得项目的Git仓库 从工作目录中初始化新仓库 git init 从现有仓库克隆 git clone ssh协议 http协议 (2) 检查当前文件状态 git status (3) ...
- IE6中布局常见问题
1.众所周知,每个IE的版本都有两种模式,怪异模式(混杂模式)和标准模式.下图附上针对IE的hack. 2.另外有一种引进css的方法,也可以作为调整网站hack的方法:<!—[if IE 6] ...
- python 循环技巧
原文地址:http://docs.pythontab.com/python/python3.4/datastructures.html#tut-tuples 在字典中循环时,关键字和对应的值可以使用 ...
- Geo-Fence
转自:http://blog.jobbole.com/86633/ 地理围栏(Geo-fencing)是LBS的一种应用,就是用一个虚拟的栅栏围出一个虚拟地理边界,当手机进入.离开某个特定地理区域,或 ...
- poj 2449 Remmarguts' Date K短路+A*
题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...
- BZOJ 2820 YY的GCD
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2820 有种方法是枚举质数然后用BZOJ2301来做但是超时了... 具体式子大概张这样: ...
- Poj 1255 覆盖的面积 2014-07-28 12:29 116人阅读 评论(0) 收藏
覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- Hibernate联合主键映射
1.联合主键的映射规则 1) 类中的每个主键属性都对应到数据表中的每个主键列. Hibernate要求具有联合主键的实体类实现Serializable接口,并且重写hashCode与equals方法, ...