mmap()将一个文件或者是其他对象映射到内存区
mmap()将一个文件或者是其他对象映射到内存区
函数说明:
#include<sys/mman.h>
void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offsize)
已PAGE_SIZE的整数倍进行映射,参数解读
start 指向预映射的地址的起始地址,通常该参数的值为NULL,由系统来决定,成功后返回该地址的值
len 代表将文件中多少数据映射到内存区
prot 映射区域的保护方式,其实就是页面的权限,由后面几个值进行组合 PROT_EXEC 页面区域可被执行 PROT_READ 页面区域可被读取 PROT_WRITE 页面可被写入 PROT_NONE 页面不能存取
fd 有效的文件描述符,一般由open函数返回,其值也可以为-1
#include <pthread.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <sys/types.h>
#include <fcntl.h>
#define FILE_MODE 0644
#define FILE_NAME "mmap"
int main(int argc, char **argv)
{
int fd, i ,nloop, zero = 0;
void *ptr;
sem_t *pMutex;
if(argc != 3)
{
printf("argc error %d\n", argc);
exit(0);
}
nloop = atoi(argv[2]);
fd = open(argv[1], O_RDWR|O_CREAT, FILE_MODE);
write(fd, &zero, sizeof(int));
ptr = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
signal(SIGCHLD,SIG_IGN);
pMutex = sem_open(FILE_NAME, O_CREAT|O_EXCL, FILE_MODE, 1);
if(pMutex == SEM_FAILED)
{
printf("semopen error\n");
exit(-1);
}
sem_unlink(FILE_NAME);
setbuf(stdout, NULL);
if(fork() == 0)
{
for(i = 0; i < nloop; i++)
{
sem_wait(pMutex);
printf("child %d\n", (*(int *)ptr)++);
sem_post(pMutex);
}
}
for(i = 0; i < nloop; i++)
{
sem_wait(pMutex);
printf("child %d\n", (*(int *)ptr)++);
sem_post(pMutex);
}
sem_close(pMutex);
exit(0);
}
Makefile
TARGET = mmap
COMPILE = -fPIC
COMPILE += -c -g
CC = g++
GCC = gcc
LINK = -lpthread
BUILD_CACHE_DIR=.buildCacheDir
ALLSRC = $(wildcard *.c)
ALL_OBJ = $(patsubst %.c, $(BUILD_CACHE_DIR)/%.o, $(filter %.c, $(ALLSRC)))
.PHYONE:all
all:createDir $(TARGET)
createDir:
@mkdir -p $(BUILD_CACHE_DIR) 2>/dev/null
# @mkdir -p $(INSTALL_PATH)/ 2>/dev/null
$(TARGET):$(ALL_OBJ)
@echo
@echo "------------------------------------------------------------------"
@echo "==== Linking $@ === "
@echo "------------------------------------------------------------------"
$(CC) $(ALL_OBJ) $(LINK) -o $@
@echo "------------------------------------------------------------------"
#编译规则
$(BUILD_CACHE_DIR)/%.o:%.cpp
$(CC) $(COMPILE) $< -o $@
$(BUILD_CACHE_DIR)/%.o:%.c
$(GCC) $(COMPILE) $< -o $@
clean:
-rm -rf $(BUILD_CACHE_DIR)