Windows 中 msync [unix sys call] 的等价物是什么?我正在 C、C++ 空间中寻找 MSDN api。有关 msync 的更多信息,请访问http://opengroup.org/onlinepubs/007908799/xsh/msync.html
3 回答
FlushViewOfFile
查看 Python 2.6 mmapmodule.c 以获取 FlushViewOfFile 和 msync 的使用示例:
/*
/ Author: Sam Rushing <rushing@nightmare.com>
/ Hacked for Unix by AMK
/ $Id: mmapmodule.c 65859 2008-08-19 17:47:13Z thomas.heller $
/ Modified to support mmap with offset - to map a 'window' of a file
/ Author: Yotam Medini yotamm@mellanox.co.il
/
/ mmapmodule.cpp -- map a view of a file into memory
/
/ todo: need permission flags, perhaps a 'chsize' analog
/ not all functions check range yet!!!
/
/
/ This version of mmapmodule.c has been changed significantly
/ from the original mmapfile.c on which it was based.
/ The original version of mmapfile is maintained by Sam at
/ ftp://squirl.nightmare.com/pub/python/python-ext.
*/
static PyObject *
mmap_flush_method(mmap_object *self, PyObject *args)
{
Py_ssize_t offset = 0;
Py_ssize_t size = self->size;
CHECK_VALID(NULL);
if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size))
return NULL;
if ((size_t)(offset + size) > self->size) {
PyErr_SetString(PyExc_ValueError, "flush values out of range");
return NULL;
}
#ifdef MS_WINDOWS
return PyInt_FromLong((long) FlushViewOfFile(self->data+offset, size));
#elif defined(UNIX)
/* XXX semantics of return value? */
/* XXX flags for msync? */
if (-1 == msync(self->data + offset, size, MS_SYNC)) {
PyErr_SetFromErrno(mmap_module_error);
return NULL;
}
return PyInt_FromLong(0);
#else
PyErr_SetString(PyExc_ValueError, "flush not supported on this system");
return NULL;
#endif
}
更新:我认为您不会在 win32 映射文件 API 中找到完全奇偶校验。FlushViewOfFile API 没有同步风格(可能是因为缓存管理器的可能影响)。如果需要精确控制何时将数据写入磁盘,也许您可以在创建映射文件的句柄时将FILE_FLAG_NO_BUFFERING
andFILE_FLAG_WRITE_THROUGH
标志与 CreateFile API 一起使用?
我怀疑 FlushViewOfFile 实际上是正确的。当我阅读msync 的手册页时,我不会假设它实际上是在刷新磁盘缓存(磁盘单元中的缓存,而不是主内存中的系统缓存)。
在磁盘堆栈完成写入之前,FlushViewOfFile 不会返回;像 msync 文档一样,它没有说明磁盘缓存中发生的情况。我们可能应该看看在文档中更清楚地说明这一点。
用于刷新所有文件映射的 Windows 等效项是
void FlushToHardDrive(LPVOID fileMapAddress,HANDLE hFile)
{
FlushViewOfFile(fileMappAddress,0); //Async flush of dirty pages
FlushFileBuffers(hFiles); // flush metadata and wait
}
并用于刷新部分文件映射
void FlushToHardDrive(LPVOID address,DWORD size, HANDLE hFile)
{
FlushViewOfFile(address,size); //Async flush of region
FlushFileBuffers(hFiles); // flush metadata and wait
}
这在 MSDN 中有所描述
标志FILE_FLAG_NO_BUFFERING
实际上对内存映射文件没有任何作用(描述here),甚至文件句柄也是用这些标志创建的,文件的元数据可以被缓存而不是刷新,所以如果你想完全确定,IO和MM总是需要FlushFileBuffers保存所有数据(包括文件访问时间)。此处描述了此行为
PS 一些现实世界的例子:SQLite 使用 MM-files 几乎只用于读取,所以当您使用 MM-files 进行写入/更新时,您需要了解这种情况的所有副作用