当前位置:嗨网首页>书籍在线阅读

17-通过映射同步文件

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

4.3.8 通过映射同步文件

POSIX提供了一种通过存储映射来同步文件的方式,它的功能等价于系统调用fsync():

169.png 调用msync()可以将mmap()生成的映射在内存中的任何修改写回到磁盘中,从而实现同步内存中的映射和被映射的文件。具体来说,文件或者文件子集在内存中的映射从addr开始的len长度字节被写回到磁盘。参数addr必须是页对齐的,通常是上一次mmap()调用的返回值。

如果不调用msync(),无法保证在映射被取消之前,修改过的映射会被写回到硬盘。这一点与write()有所不同,被write()修改的缓冲区被保存在一个队列中等待被写回。而当向内存映射写数据时,进程会直接修改内核页缓存中的文件页,而无需经过内核。内核不会立即同步页缓存到硬盘。

参数flag控制同步操作的行为。它的值是以下值的按位或操作结果:

MS_SYNC

指定同步操作必须同步进行。直到所有页写回磁盘后,msync()调用才会返回。

MS_ASYNC

指定同步操作应该异步执行。更新操作是由系统调度的,而msync()调用会立即返回,不用等待write()操作完成。

MS_INVALIDATE

指定所有其他的该块映射的拷贝都将失效。后期对该文件的所有映射区域上的访问操作都将直接同步到磁盘。

MS_ASYNC和MS_SYNC必须指定其一,但二者不能共用。

msync()的用法很简单:

170.png 这个例子是以异步方式把文件的映射区域[addr, addr+len)同步到磁盘。

返回值和错误码

成功时,msync()返回0。失败时,返回-1,并相应设置errno值。以下为有效的errno值:

EINVAL

参数flags同时设置了MS_SYNC和MS_ASYNC(设置成除以上三个合法参数值外的其他值),或者参数addr没有页对齐。

ENOMEM

指定的内存区域(或其中一部分)没有被映射。注意,按POSIX规定,Linux在处理请求同步一块部分被解除映射的内存时,会返回ENOMEM,但是它依然会同步该区域中所有有效的映射。

在Linux内核2.4.29版本之前,msync()会返回EFAULT,而不是ENOMEM。