您的位置:首页 > 其它

文件缓冲内容写到磁盘

2012-03-30 10:09 483 查看
c语言中的:标准IO

都有缓存区,这和系统缓冲不同,我们使用fflush()只保证了将IO缓冲写入系统缓冲中,使IO读操作能成功,但系统什么时候写入磁盘,由系统决定,一般是达到一定量时系统他就写入磁盘。当然可以强制系统将系统文件缓冲的内容写入磁盘:linux中可以使用sync命令或sync系统调用<unistd.h>

命令sync(1)也调用sync函数。

值得注意的是sync函数只是将所有修改过的块缓冲区排入写队列,然后它就返回,它并不等待实际写磁盘操作结束,幸运的是,通常成为update的系统守护进程会周期(30s)调用sync函数,这就保证了定期冲洗内核的块缓冲区,所以我们在linux上更新一个文件后,不要着急重启服务器,最好等待实际的磁盘写操作完成,避免数据丢失。

#include <unistd.h>

void sync(void) /int fsync(int fildes)/int fdatasync(int fildes)

sync系统调用,同步数据到磁盘,fdatasync之同步数据,fsync还会同步metadata,这三个函数都不能保证所有改动写会了磁盘,如上说是将改动后的数据插入写队列

注意标准IO对文件的写入,对多线程是安全的,但c++中的流则不是。-------------c++中的流也同上

系统调用中的read/write是将内容直接写到系统的文件缓冲区。

当closeIO时会使用系统尽快将内容写入磁盘同时释放对应的系统缓冲区。所以写完的IO应该尽快关闭。否则一部分系统缓冲区不能及时释放导致可使用内存减少。
不太对:请参看:http://openbrd.5d6d.com/archiver/tid-32.html

********************************************************************************************************

文件描述符如下使用:

linux:

#include <stdio.h>

#include <unistd.h>

FILE* fp = fopen("./test.dat", "w+");

fwrite(buffer, size, 1, fp);

int fd = ::fileno(fp); //获取文件描述符

::fsync(fd); //强制写硬盘

windows:

#include <stdio.h>

#include <io.h>

FILE* fp = fopen("./test.dat", "w+");

fwrite(buffer, size, 1, fp);

int fd = _fileno(fp); //获取文件描述符

_commit(fd); //强制写硬盘

***********************************************************************************************************

如果打开IO然后一天才关闭,中间对IO大量的写入,这样会是内存使用飙升,容易耗尽内存,当如果是日志服务器,每秒要写入的东西很多则要考虑。

while(1)

{

usleep(100);

fprintf(fp, "0000000000000\n");

}

然后看见内存使用飘升

Linux下如何释放内存----转

在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好。但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了。

Linux系统的缓存机制是相当先进的,他会针对dentry(用于VFS,加速文件路径名到inode的转换)、Buffer Cache(针对磁盘块的读写)和Page Cache(针对文件inode的读写)进行缓存操作。但是在进行了大量文件操作之后,缓存会把内存资源基本用光。但实际上我们文件操作已经完成,这部分缓存已经用不到了。这个时候,我们难道只能眼睁睁的看着缓存把内存空间占据掉么?

所以,我们还是有必要来手动进行Linux下释放内存的操作,其实也就是释放缓存的操作了。

要达到释放缓存的目的,我们首先需要了解下关键的配置文件/proc/sys/vm/drop_caches。这个文件中记录了缓存释放的参数,默认值为0,也就是不释放缓存。他的值可以为0~3之间的任意数字,代表着不同的含义:

0 – 不释放

1 – 释放页缓存

2 – 释放dentries和inodes

3 – 释放所有缓存

知道了参数后,我们就可以根据我们的需要,使用下面的指令来进行操作。

首先我们需要使用sync指令,将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。否则在释放缓存的过程中,可能会丢失未保存的文件。

#sync

接下来,我们需要将需要的参数写进/proc/sys/vm/drop_caches文件中,比如我们需要释放所有缓存,就输入下面的命令:

#echo 3 > /proc/sys/vm/drop_caches

此指令输入后会立即生效,可以查询现在的可用内存明显的变多了。

要查询当前缓存释放的参数,可以输入下面的指令:

#cat /proc/sys/vm/drop_caches
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: