mmap、msync 函数

mmap

UNIX 提供了一个有用的功能以运行程序共享内存。mmap(内存映射)函数的作用是建立一段可以被两个或更多个程序读写的内存。一个程序对它所做出的修改可以被其他程序看见。

这一功能还可以用在文件的处理上。你可以使某个磁盘文件的全部内容看起来就像是内存中的一个数组。如果文件由记录组成,而这些记录又能够C语言中的结构来描述的话,你就可以通过访问结构数组来更新文件的内容了。

mmap 函数创建一个指向一段内存区域的指针,该内存区域与可以通过一个打开的文件描述符访问的文件的内容相关联。

#include <sys/mman.h>
void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off);

函数的返回值为最后文件映射到进程空间的地址,进程可直接操作起始地址为该值的有效地址。

addr

参数addr指定文件应被映射到进程空间的起始地址,一般被指定一个空指针,此时选择起始地址的任务留给内核来完成。

len

可以访问的数据量(内存段的长度)。

prot

用于设置内存段的访问权限,是下列常数值的按位 OR 结果。

  • PROT_READ 允许读该内存段。
  • PROT_WRITE 允许写该内存段。
  • PROT_EXEC 允许执行该内存段。
  • PROT_NONE 该内存段不能被访问。

flags

  • MAP_PRIVATE 内存段是私有的,对它的修改只对本进程有效。
  • MAP_SHARED 把对该内存段的修改保存到磁盘文件中。
  • MAP_FIXED 该内存段必须位于 addr 指定的地址处。

fildes

打开的文件描述符。

off_t off

改变经共享内存段访问的文件中数据的起始偏移地址。

msync

把在该内存段的某个部分或者整段中的修改写回到被映射的文件中(或者从被映射文件里读出)。

#include <sys/mman.h>
int msync(void* addr, size_t len, int flags);

内存段需要修改的部分作为参数传递过来的起始地址addr和长度len确定。

flags 参数控制着执行修改的具体方式:

  • MS_ASYNC 采用异步写方式
  • MS_SYNC采用同步写方式
  • MS_INVALIDATE 从文件中读回数据

munmap

释放内存段。

int munmap(void* addr, size_t len);
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>

typedef struct{
	int integer;
	char string[24];
} RECORD;

#define NRECORDS (100)

int main()
{
	RECORD record, *mapped;
	int i, f;
	FILE *fp;
	
	fp = fopen("records.dat", "w+");
	for(i = 0; i < NRECORDS; i++)
	{
		record.integer = i;
		sprintf(record.string, "RECORD-%d", i);
		fwrite(&record, sizeof(record), 1, fp);
	}
	fclose(fp);

	// exit(0);

	fopen("records.dat", "r+");
	fseek(fp, 43*sizeof(record), SEEK_SET);
	fread(&record, sizeof(record), 1, fp);

	record.integer = 143;
	sprintf(record.string, "RECORD-%d", record.integer);

	fseek(fp, 43*sizeof(record), SEEK_SET);
	fwrite(&record, sizeof(record), 1, fp);
	fclose(fp);


	f = open("records.dat", O_RDWR);
	mapped = (RECORD*)mmap(0, NRECORDS*sizeof(record), PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
	mapped[43].integer = 243;
	sprintf(mapped[43].string, "RECORD-%d", mapped[43].integer);

	msync((void*)mapped, NRECORDS*sizeof(record), MS_ASYNC);
	munmap((void*)mapped, NRECORDS*sizeof(record));
	close(f);
	exit(0);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jia ming

谢谢投食哦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值