Linux允许任何进程把一个磁盘文件映像到内存中。
使用内存映像文件有两个主要优点
–加速文件I/O操作,不同的I/O调用如read或者fputs通过内核缓冲读出或写入数据。虽然Linux具有一种快速而先进的磁盘缓冲算法,但最快的磁盘访问也总是要比最慢的内存访问慢。
–共享数据,如果多个进程要访问一样的数据,这些数据就可以保存在一个内存映像文件中,所有的进程都可以访问它。
mmap函数
#include <unistd.h>
#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
在文件描述符fd指定打开的文件中,从文件起始处offset位置开始映像文件到内存start开始的地方。
offset通常为0,代表整个文件都映像到内存中。
length指定了文件被映像的大小。
执行成功返回指向内存区域的指针,失败返回-1,并设置errno变量
参数prot---保护模式
–其值可以逻辑“或”
值 |
说明 |
PROT_NONE |
不允许访问 |
PROT_READ |
内存可读 |
PROT_WRITE |
内存可写 |
PROT_EXEC |
内存可执行 |
参数flags---映像的属性
–其值可以逻辑“或”
值 |
说明 |
MAP_FIXED |
如果start无效或者正在使用则失败 |
MAP_PRIVATE |
对映像内存区域的写入操作是进程私有的 |
MAP_SHARED |
对映像内存区域的写入操作也被复制到文件 |
映像内存区域必须用MAP_PRIVATE标为私有或者用MAP_SHARED标为可共享。
munmap函数
int munmap(void *start, size_t length)
当使用完一个内存映像文件后,需要调用munmap解除内存映像,并把内存释放返回给操作系统。
参数start指向要解除映像的内存区域起始位置。
参数length指定了被释放内存区域的大小。
执行成功返回指向内存区域的指针,失败返回-1,并设置errno变量。
当一块内存解除映像后,再尝试访问start,会导致一个段错误
当一个进程终止时,所有的内存映像都会被解除
mmap、munmap函数例子
int main() { int fdin = open("aaa.txt", O_RDONLY); struct stat statbuf; fstat(fdin, &statbuf); off_t len = statbuf.st_size; char *s = mmap(0, len, PROT_READ, MAP_SHARED, fdin, 0); printf(s); munmap(s, len); close(fdin); return 0; }
msync函数
int msync(const void *start, size_t length, int flags)
msync函数把被映像的文件写入磁盘。
参数flags可以使下面值的一个或多个“或”。
–MS_ASYNC—调用一次写入操作后返回。
–MS_SYNC—在msync返回前写入数据。
–MS_INVALIDATE—让映像到同一个文件的映像无效,以便新数据更新它们。
msync函数例子
int main() { int fdin = open("aaa.txt", O_RDWR); struct stat statbuf; fstat(fdin, &statbuf); off_t len = statbuf.st_size; char *s = mmap(0, len, PROT_WRITE | PROT_READ, MAP_SHARED, fdin, 0); printf(s); strcpy(s, "hello world"); msync(s, len, MS_SYNC); munmap(s, len); close(fdin); return 0; }
锁定内存
int mlock(const void *start, size_t len);
int munlock(void *start, size_t len);
Linux系统,如果在一段时间内存不被访问,可能会将内存数据暂时写入交换分区(磁盘的一个特殊区域)。
锁定内存就是设置一个标志,防止系统将内存数据写入交换分区。
只有root用户才有权限对内存区域进行锁定。
int mlock(const void *start, size_t len);
int munlock(void *start, size_t len);
Linux系统,如果在一段时间内存不被访问,可能会将内存数据暂时写入交换分区(磁盘的一个特殊区域)。
锁定内存就是设置一个标志,防止系统将内存数据写入交换分区。
只有root用户才有权限对内存区域进行锁定。