关于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都通过缓冲进行.当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列 ...
随机推荐
- JS中关于clientWidth offsetWidth scrollWidth 的区别及意义
网页可见区域宽: document.body.clientWidth;网页可见区域高: document.body.clientHeight;网页可见区域宽: document.body.offset ...
- Azure MySQL PaaS (3) 创建MySQL异地只读数据库 (Master-Slave)
<Windows Azure Platform 系列文章目录> Azure MySQL PaaS服务提供异地只读的功能,我们可以在主站点,比如Azure上海数据中心,创建MySQL主节点. ...
- HTML基本结构与标签总结整理篇
HTML基本结构与标签总结整理篇 前言:这是笔者的学习总结与整理,如果有错误或疑问的地方,欢迎指正与讨论!另:此文会不定时更新~ 1.了解HTML 学习前端技术,必然涉及三个方面:html(结构).c ...
- 底层码农的Stanford梦 --- 从SCPD开始 [转]
转载自知乎: https://zhuanlan.zhihu.com/p/25010074 一开始让我写这篇文章的时候,我是拒绝的.毕竟,我不是Stanford毕业的,出来写文章介绍Stanford,难 ...
- servlet导出Excel
package khservlet; import java.io.IOException;import java.io.PrintWriter;import java.sql.*; import j ...
- 如何编写高效的SQL
编写高效的sql可以给用户带来好的体验,需要开发这没有意识到这一点因为他们不关心也不知道怎么做.高效的sql可以给用户节省很多时间,这样就不需要dba来找上门,也不需要搭建RCA和性能调优. 性能不好 ...
- EasyNetQ之多态发布和订阅
你能够订阅一个接口,然后发布基于这个接口的实现. 让我们看下一个示例.我有一个接口IAnimal和两个实现Cat和Dog: public interface IAnimal { string Name ...
- eclipse 下使用git clone
方法一:eclipse安装好git插件后,直接import-git-project from git- clone url-输入github的网址等就可以了方法二:使用git软件,到指定的目录,右击g ...
- (一)SQL关联查询的使用技巧 (各种 join)
---恢复内容开始--- (一)SQL关联查询的使用技巧 (各种 join) 这几天因为工作的时候,发现自己的sql语句基础不是很好,特意研究了一下,发现sql语句真的是博大精深,sql语句不仅是要查 ...
- PHP对MySQL数据库的相关操作
一.Apache服务器的安装 <1>安装版(计算机相关专业所用软件---百度云链接下载)-直接install<2>非安装版(https://www.apachehaus.com ...