如何判断boost::mapped_file_sink内存映射文件已刷至磁盘?
Let’s break down your questions with practical, OS-aware solutions since Boost doesn’t handle this directly:
1. Does Boost offer a built-in way to check if mapped data is flushed to disk?
Short and clear: No, boost::mapped_file_sink doesn’t include a function to confirm data has been fully written to disk. Memory-mapped file synchronization is tied to low-level OS kernel behavior, and Boost intentionally avoids tying itself to platform-specific checks here.
2. How to safely move the file only after data is flushed?
Since we can’t rely on Boost for this, we need to use OS-native synchronization APIs to guarantee data hits the disk before moving the file. Here’s how to implement this across major platforms:
On Linux/Unix-like systems
Use the msync() system call, which blocks until all changes in the mapped region are written to disk. You can grab the mapped memory address and size directly from mapped_file_sink:
#include <boost/interprocess/mapped_file_sink.hpp> #include <cstring> #include <cerrno> #include <cstdio> int main() { boost::interprocess::mapped_file_sink sink("target_file.txt", 2048); // Write your data to the mapped region char* buffer = static_cast<char*>(sink.data()); std::strcpy(buffer, "Data that must be on disk before moving!"); // Force synchronous flush to disk if (msync(buffer, sink.size(), MS_SYNC) == -1) { perror("Failed to sync mapped file to disk"); return 1; } // Now it's safe to move the file if (std::rename("target_file.txt", "target_file_moved.txt") == -1) { perror("Failed to move file"); return 1; } return 0; }
On Windows
Use FlushViewOfFile() to flush the mapped memory to disk, and optionally FlushFileBuffers() to ensure file metadata (like size updates) is also synced:
#include <boost/interprocess/mapped_file_sink.hpp> #include <cstring> #include <windows.h> int main() { boost::interprocess::mapped_file_sink sink("target_file.txt", 2048); // Write your data to the mapped region char* buffer = static_cast<char*>(sink.data()); std::strcpy(buffer, "Data that must be on disk before moving!"); // Flush the mapped view to disk if (!FlushViewOfFile(buffer, sink.size())) { DWORD error = GetLastError(); // Handle error (log, print, etc.) return 1; } // Optional: Flush file metadata to disk HANDLE file_handle = CreateFileA("target_file.txt", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (file_handle != INVALID_HANDLE_VALUE) { FlushFileBuffers(file_handle); CloseHandle(file_handle); } // Now safely move the file if (!MoveFileA("target_file.txt", "target_file_moved.txt")) { DWORD error = GetLastError(); // Handle error return 1; } return 0; }
Critical Tips:
- Always validate return values: OS sync functions can fail (e.g., disk I/O errors), so don’t skip error handling—this prevents silent data loss.
- Unmapping vs. explicit sync: When
mapped_file_sinkgoes out of scope, Boost unmaps the region, and the OS will usually flush pending writes. But this isn’t reliable if you need to move the file before closing the sink. - Cross-platform support: Wrap OS-specific code in conditional compilation (e.g.,
#ifdef _WIN32/#ifdef __linux__) if your project needs to run on multiple systems.
内容的提问来源于stack exchange,提问作者david

