Memory mapped file class, threads and reference counting
我正在整理一个类,我要调用文件。
文件对象仅包含指向内存映射文件的指针和链接。
构造函数获取一个文件,并将该文件映射到内存范围。总而言之
有点像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class file { public: file(unsigned char* filename) { open(filename); } open(unsigned char* filename) { /// snip length_ = fstat(.....) file_ = mmap(.....) } private: unsigned int length_; unsigned char* bytes_; }; |
现在,可以复制该文件对象。
乐趣来了。通常,像这样的类将需要深度复制构造函数来复制bytes_。但是,我很满意我可以复制指针,因为内存是共享的,并且无论如何它应该查看相同的文件。我不要
重新映射文??件。但是,很明显,在某些情况下要防止内存泄漏bytes_
需要释放。
我可以使用哪些机制来决定何时删除内存和munmap?
我当时正在考虑使用boost :: shared_ptr以便仅在最后一个引用时释放析构函数中的内存,但是我必须使用互斥锁来保护它吗?
我已经可以使用一些便捷的boost功能了吗?我不想引入另一个大库,这不是一个选择。
即
1 2 3 4 5 6 7 8 9 10 11 | boost::shared_ptr<unsigned char> bytes_; ~file() { // enter some sort of critical section if (bytes_.unique()){ munmap(bytes_); bytes_ = 0; } // exit critical section } |
我会做些不同。
问题在于
简单的替代方法是使用Pimpl习惯用语:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class FileImpl: boost::noncopyable { public: FileImpl(char const* name): mLength(fstat(name)), mFile(mmap(name)) {} ~FileImpl() { munmap(mFile); } unsigned int GetLength() const { return mLength; } unsigned char* GetFile() const { return mFile; } private: unsigned int mLength; unsigned char* mFile; }; class FileHandle { public: FileHandle(char const* name): mFile(new FileImpl(name)) {} void open(char const* name) { mFile = new FileImpl(name); } private: boost::shared_ptr<FileImpl> mFile; }; |
在销毁过程中,您将不会有任何同步问题(由
您可能还希望使用
shared_ptr是线程安全的,如注释中张贴的链接编号所述。
另一种选择是将复制构造函数和赋值运算符声明为私有,从而允许(强制?)用户根据自己的情况选择适当的管理策略,例如shared_ptr或ptr_container。添加移动语义以进一步提高灵活性。
查看Boost提供的互斥锁(和其他同步机制)。看到这个。另外,Boost有一个线程库。您是否在使用特定于操作系统的线程库?如果是这样,Boost.Threads可能值得一看。另外,您的