mmap()是一个非常重要的系统调用,这仅从mmap本身的功能描述上是看不出来的。从字面上看,mmap就是将一个文件映射进进程的虚拟内存地址,之后就可以通过操作内存的方式对文件的内容进行操作,上代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/file.h>
#include <wait.h>
#include <sys/mman.h>
#define COUNT 100
#define SHMPATH "shm"
#define MEMSIZE 1024 * 1024 * 1023 * 2
int main()
{
pid_t pid;
int count, shmfd, ret;
int *shm_p;
/* 创建一个POSIX共享内存 */
if ((shmfd = shm_open(SHMPATH, O_RDWR | O_CREAT | O_EXCL, 0644)) >= 0)
{
printf("1.shm id:%d", shmfd);
ftruncate(shmfd, MEMSIZE);
}
else if (errno == EEXIST)
{
if ((shmfd = shm_open(SHMPATH, O_RDWR | O_CREAT, 0644)) >= 0)
{
printf("1. exist shm id:%d", shmfd);
ftruncate(shmfd, MEMSIZE);
}
}
if (shmfd < 0) {
perror("shm_open()");
exit(1);
}
printf("3. shm id:%d", shmfd);
/* 使用mmap将对应的tmpfs文件映射到本进程内存 */
shm_p = (int *)mmap(NULL, MEMSIZE, PROT_WRITE|PROT_READ, MAP_SHARED| MAP_ANON, shmfd, 0);
if (MAP_FAILED == shm_p) {
perror("mmap()");
exit(1);
}
int *pTmp = shm_p;
int i = 0;
for (i = 0; i < MEMSIZE/sizeof(int); i++)//开始读入到内存,需要整整的用到所有文件才会占用cache空间
{
*pTmp = i;
++pTmp;
}
getchar();
printf("shm_p: %d\n", *shm_p);
munmap(shm_p, MEMSIZE);//解除隐射才能释放cache空间
close(shmfd);
//shm_unlink(SHMPATH);//会删除shm_open留下来的文件
getchar();
}
运行之前先查看服务器内存:
运行程序:
可以看到前后运行期间free的内存减少了2个G,最后结束程序之后进入可以看到:
这里值得一提的是假如代码最后加入shm_unlink调用,在程序结束会删除我们在程序运行期间使用shm_open创建的shm文件,假如不适用这个函数,则之前创建的shm文件则会保存下来并在下次打开使用。
参考文章: