我正在编写一个使用文件映射注销到文件的程序。
当我想读取日志时,Logger::Destroy()
会调用,以便将文件映射视图上写入的内容刷新到物理文件中。代码如下:
int Logger::Destroy() {
if (m_lpMapAddress) {
auto bRet = UnmapViewOfFile(m_lpMapAddress);
// succeed
}
if (m_hMapFile) {
auto bRet = CloseHandle(m_hMapFile);
// succeed
m_hMapFile = NULL;
}
int nSize = m_lpCurAddress - m_lpMapAddress;
if (nSize > 0
&& nSize < (1024 * 1024 * 16 * 2))
{
DWORD dwPtr = SetFilePointer(m_hFile, nSize, 0, FILE_BEGIN);
///// Succeed
// if (dwPtr == INVALID_SET_FILE_POINTER)
// DbgViewOut(__FUNCTION__ " SetFilePointer error: %d \n", GetLastError());
//// Error occurs : "SetEndOfFile returned : 0 1224"
BOOL bRet = SetEndOfFile(m_hFile);
DbgViewOut(__FUNCTION__ " SetEndOfFile returned : %d %d\n", bRet, GetLastError());
....
}
m_lpMapAddress = m_lpCurAddress = NULL;
return 0;
}
问题是SetEndOfFile()
失败了ERROR_USER_MAPPED_FILE
,甚至CloseHandle(m_hMapFile)
成功了。所以我用谷歌搜索了微软关于文件映射的手册,并对其中的一些进行了评论。
https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
即使有仍然打开的文件视图,关闭文件映射的句柄也可以成功。有关详细信息,请参阅关闭文件映射对象。
https://docs.microsoft.com/en-us/windows/win32/memory/closing-a-file-mapping-object
当每个进程完成使用文件映射对象并取消映射所有视图时,它必须通过调用 CloseHandle 关闭文件映射对象的句柄和磁盘上的文件。即使有仍然打开的文件视图,这些对 CloseHandle 的调用也会成功。但是,保留文件视图映射会导致内存泄漏。
它说我无法相信 的结果CloseHandle()
。
而且我找不到解决方案。
任何人都可以帮助我吗?谢谢。
补充:我打
Logger::Destroy()
进来了std::lock_guard<std::mutex>
,这对麻烦有影响吗?: 我已经测试过了,锁不影响它。
更新:我已阅读何时出现错误 1224:ERROR_USER_MAPPED_FILE?. 而且我认为没有太大的区别。我附加了
Logger::Initialize()
初始化文件映射的代码。
而且,Logger::Initialize()
两者Logger::Destroy()
都在同一个进程和线程中,无需与他人共享。int Logger::Initialize() { m_hFile = CreateFileA( m_zFileName.c_str() , GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); if (m_hFile == INVALID_HANDLE_VALUE) { DbgViewOut(__FUNCTION__ " CreateFileA error: %d \n", GetLastError()); return -1; } m_hMapFile = CreateFileMappingA( m_hFile , NULL , PAGE_READWRITE , 0 , 1024 * 1024 * 16 * 2 , m_zMapKey.c_str()); if (!m_hMapFile) { DbgViewOut(__FUNCTION__ " CreateFileMapping error: %d \n", GetLastError()); return -1; } m_hMapFile = OpenFileMappingA(FILE_MAP_WRITE, TRUE, m_zMapKey.c_str()); if (m_hMapFile == NULL) { DbgViewOut(__FUNCTION__ " OpenFileMapping error: %d \n", GetLastError()); return -1; } m_lpMapAddress = (BYTE*)MapViewOfFile( m_hMapFile // handle to mapping object , FILE_MAP_ALL_ACCESS // read/write , 0 // high-order 32 bits of file offset , 0 // low-order 32 bits of file offset , 0); // number of bytes if (m_lpMapAddress == NULL) { DbgViewOut(__FUNCTION__ " MapViewOfFile error: %d \n", GetLastError()); return -1; } m_lpCurAddress = m_lpMapAddress; return 0; }