关于write()和fsync()
--关于write()和fsync()
----------------------------转载
write
ssize_t write(int fd, const void *buf, size_t count);
将数据写到文件中. 注意, 如果文件是保存在硬盘中, write() 函数调用返回之后, 并不表示数据已经写入到硬盘中, 这时如果掉电, 数据可能会丢失.
fsync
int fsync(int fd);
程序调用本函数, 通知内核把数据写到硬盘(file)中. 比如, 你开发一个数据库软件, 就需要这样的函数, 否则掉电或者系统崩溃时便会丢失数据.
如果你的程序不调用 fsync(), Linux 内核也会自动在”合适”的时候将你的数据真正写入到硬盘(类似调用 fsync), 最长的延时默认是 30 秒.
阻塞
阻塞是 IO 的精华所在, 不管是文件 IO 还是网络 IO, 只有真正了理解了 IO 阻塞, 才能做出所谓在高并发高性能软件(服务器).
当 fsync() 和 write() 同一个 fd 时, write() 必然阻塞. 当系统 IO 非常繁忙时, fsync() 可能会阻塞, 即使系统 IO 不繁忙, fsync() 也会因为数据量大而慢.
注: 许多 Linux 系统函数如 read(), write() 等, 粗看起来很简单, 也很容易用. 正如所有的事情一样, 要做到精致肯定不简单. 当你脱离初级的学习阶段, 要写真正生产环境的软件时, 这些”简单”的函数就大有门道了. 你需要不断的阅读它们的手册, 了解每一个参数, 每一个返回值, 同时还要阅读和试验在各种条件和环境下这些函数的表现, 这样, 才有可能做出真正的软件.
关于write()和fsync()
楼主password636(亮)2006-03-02 18:08:38 在 Linux/Unix社区 / 程序开发区 提问
关于linux系统调用write()
调用一次write()完毕,是不是已经写到磁盘上了?
是不是调用一次write(),就是一次写请求,不管写多少个字符进去,调用完都已经通过缓冲区写到磁盘上了?
那么fsync()这个函数是不是指将缓冲区的写到磁盘上,如果是,write完再fsync是不是多此一举?
我想实现的是可以先创建一个文件,然后写一些东西到该文件的缓冲区,再调用fsync()写入磁盘,请问如何实现?
问题点数:10、回复次数:7Top
1 楼morpheus1977()回复于 2006-03-03 22:07:46 得分 0
write() 是不带缓存的。 应该不用吧。Top
2 楼tb01412(tb)回复于 2006-03-03 22:49:08 得分 0
所谓write不带缓存是指不在C库中缓存,只要应用层调用write,就直接发出write系统调用,而内核中的write块设备都是有缓存的,所以就需要fsync将磁盘高速缓冲中的数据立刻写入磁盘中去!!!!!Top
3 楼password636(亮)回复于 2006-03-04 12:32:50 得分 0
但是为什么我write()完后,用stat()输出st_size,就是写入的个数呢?要是有缓存,应该是0啊?Top
4 楼tb01412(tb)回复于 2006-03-04 13:11:31 得分 10
呵呵,当你用write之后,内核就响应write系统调用,然后向高速磁盘缓冲块写入数据,之后,你如果用stat,或者read时,系统首先会在高速缓冲块中去查看相应的数据是否在块中,如果不是,然后再调用磁盘驱动加载磁盘数据到高速缓冲块中,然后再由高速缓冲块中返回你要的数据!!!!!这就是你用stat()输出st_size,就是写入的个数的原因!!!!!
系统会在合适的时机再向真正的硬件写入高速缓冲块中的数据,也可以用fsync强制把高速缓冲块中的相应数据写入磁盘!!!!!!!Top
5 楼password636(亮)回复于 2006-03-05 18:31:56 得分 0
如何能证明fsync()是强制从缓存写到磁盘上的?
我开始想证明fsync()是这样打算的,用open()创建一个文件,用write()写,然后用stat()获得一个size,之后调用fsync(),调用完后再用stat()获得一次size,开始由于对stat()的不理解,觉得stat()是从磁盘上读大小,第一次读应该是0,第二次即fsync()后读应该是write()进去的大小,可现在知道了stat()和read()都是从缓存中获得数据,那么有没有其他的办法在write()后fsync()前获得文件在磁盘上的大小?如果获得不了,那有什么办法能证明fsync()是从缓存强制写到磁盘上的?Top
6 楼tb01412(tb)回复于 2006-03-06 13:05:56 得分 0
如果只想证明fsync()是从缓存强制写到磁盘上的话,很简单:
使用U盘,你先向上面写入大量的数据(比如几十M),接着程序退出,然后马上拔出U盘(不要用umount),之后再将U盘插入,mount上去,然后再读出原来的文件内容,估计文件最后的内容不再是你原来写入的内容了!!!!
还有一种办法:
不通过磁盘缓冲读取数据,比如你想读sda1上的文件数据,直接用open("/dev/sda1"),而不再用实际文件目录的方式来操作,不过这样你需要自己去解析相应文件系统在磁盘上的物理组织格式才行Top
7 楼fgmIsdn()回复于 2006-03-09 15:37:43 得分 0
缓冲区有多个层次,OS内核肯定有,驱动程序也可能有,而且现在流行的硬盘驱动器上也有。
fsync()一般不要使用,立即写入硬盘磁介质上,会产生很多次写入动作,有损硬盘寿命,硬盘的性能也会收到影响。
硬盘涉及到比较复杂的技术。
目前IDE硬盘从2MB缓存向8MB缓存过渡,大容量有16MB的。
关于write()和fsync()的更多相关文章
- linux 同步IO: sync msync、fsync、fdatasync与 fflush
最近阅读leveldb源码,作为一个保证可靠性的kv数据库其数据与磁盘的交互可谓是极其关键,其中涉及到了不少内存和磁盘同步的操作和策略.为了加深理解,从网上整理了linux池畔同步IO相关的函数,这里 ...
- Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式
Linux就这个范儿 第15章 七种武器 linux 同步IO: sync.fsync与fdatasync Linux中的内存大页面huge page/large page David Cut ...
- Linux系统调用---同步IO: sync、fsync与fdatasync【转】
转自:http://blog.csdn.net/cywosp/article/details/8767327 [-] 1 write不够需要fsync 2 fsync的性能问题与fdatasync ...
- 同步内核缓冲区sync、fsync和fdatasync函数
转自http://www.2cto.com/os/201409/339460.html 同步内核缓冲区 1.缓冲区简介 人生三大错觉之一:在调用函数write()时,我们认为该函数一旦返回,数据便已经 ...
- 文件I/O之sync、fsync和fdatasync函数
传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲进行.当将数据写入文件时,内核通常先将数据复制到其中一个缓冲区中,如果 该缓冲区尚未写满,则并不将其排入输出队列, ...
- mysql strace fsync,fdatasync
mysql> show create table y; +-------+------------------------------------------------------------ ...
- LINUX 文件系统JBD ----深入理解Fsync
http://www.cnblogs.com/hustcat/p/3283955.html http://www.cnblogs.com/zengkefu/p/5639200.html http:// ...
- sync fsync fdatasync ---systemtap跟踪
aa.stp: probe kernel .function ( "sys_sync" ) { printf ( "probfunc:%s fun:%s\n", ...
- mysql在高内存、IO利用率上的几个优化点 (sync+fsync) 猎豹移动技术博客
http://dev.cmcm.com/archives/107 Posted on 2014年10月16日 by liuding | 7条评论 以下优化都是基于CentOS系统下的一些优化整理,有不 ...
- 《UNIX环境高级编程》笔记--sync、fsync和fdatasync函数
传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘 I/O都通过缓冲进行.当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列 ...
随机推荐
- 探索Windows命令行系列(7):通过命令编译C#类和Java类
1.编译 C# 类 1.1.C# 编译工具 1.2.编译一个 C# 类 1.3.编译多个 C# 类 2.编译 Java 类 2.1.Java 编译工具 2.2.编译 Java 类 3.组合命令符 4. ...
- Azure SQL Database (23) Azure SQL Database Dynamic Data Masking动态数据掩码
<Windows Azure Platform 系列文章目录> 我们在使用关系型数据的时候,有时候希望: - 管理员admin,可以查看到所有的数据 - 普通用户,某些敏感字段,比如信用卡 ...
- Linux系统安全配置基线
一:共享账号检查 配置名称:用户账号分配检查,避免共享账号存在 配置要求:1.系统需按照实际用户分配账号: 2.避免不同用户间共享账号,避免用户账号和服务器间通信使用的账号共享. 操作指南:参考配置操 ...
- Exception in thread "main" java.lang.NoClassDefFoundError: javax/transaction/Synchronization
解决办法:原因是缺少jta.jar包,添加jta.jar包就好
- Vijos 1002 过河 状态压缩DP
描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上 ...
- 安装 Node 和 gulp
gulp 是基于 node 实现的,那么我们就需要先安装 node. Node 是一个基于Chrome JavaScript V8引擎建立的一个平台,可以利用它实现 Web服务,做类似PHP的事. 打 ...
- Tomcat集群搭建
关于如何搭建Tomcat集群网上还是能搜到很多相关的教程,这里结合我自己在实际应用中的操作做下备忘. 案例说明: 这里以在本机部署的2个tomcat来做集群.当然,tomcat集群可以是分布式的,而差 ...
- 一只猿:使用flask来做一个小应用
上周 @萍姐 问我如何抓取天猫上面店铺的评分,看了下挺简单的,于是花了点时间写了个Python脚本,加上web.py做成一个web服务,使用起来还不错,今天来看的时候发现当时为了方便直接用web.py ...
- c#Message多功能用法
1. 当要显示如图3个按钮时,并要获得单击不同按钮的进行不同的相应时,可以在MessageBoxButtons后面添加一个.(应该英文的点,此处为了醒目,用中文代替)可以看到提示框下方需要几个按 ...
- Android 动画——Frame Animation与Tween Animation
很多手机应用的引导页都是动画的,添加动画后的应用画面会更加生动灵活,今天博主也学习了Android中Animation的使用,下面来总结下. android中的Animation分为两种,一种是Fr ...