NAME
mmap, munmap - map or unmap files or devices into memory
SYNOPSIS
#include <sys/mman.h>
/* 映射,返回值为映射到的最终地址。
addr: 目标内存空间 放到当前进程空间的起始地址,若为空,则函数自己找可用的位置
length:需要映射目标空间的长度
port : 映射过来的内存属性,即可以对该内存做什么操作,即映射后的操作权限
PROT_EXEC Pages may be executed.
PROT_READ Pages may be read.
PROT_WRITE Pages may be written.
PROT_NONE Pages may not be accessed.
flags :标记,特殊要求,位图
必选:
MAP_SHARED : 进程对进程对映射过来的内存修改,会同步到真实的内存空间。
MAP_PRIVATE:进程对映射过来的内存修改,只是改动当前进程空间中目标内存空间,不会同步到真实的内存空间
可选:
如:MAP_ANONYMOUS 匿名映射,当前映射不依赖于任何文件(fd选项为-1),类似于 malloc()功能,空间会被初始化为0
fd : 文件描述符,如 需要映射一个文件过来,那么需要先将目标文件打开。
offset :偏移量
从 fd 文件的 offset偏移量开始映射,映射length长度的空间到当前进程空间的addr地址,空间权限设置为port ,特殊要求是flags
*/
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
/*解除映射
对 addr地址处 映射过来的空间(大小为length) 进行解除映射
如果 mmap()的时候 flags 有MAP_ANONYMOUS 匿名映射要求,则此处munmap() 类似于 free()
*/
int munmap(void *addr, size_t length);
实例:
父子间同时改变共享内存的值,用无名信号量同步
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/wait.h>
#define PATHNAME "/tmp/out"
int main(int argc, char **argv)
{
sem_t *semp = NULL;
key_t key;
int shmid;
int proc_id = 1;
size_t size = 4096;
int *shmp = NULL;
pid_t pid;
int n = 100000LL;
key = ftok(PATHNAME, proc_id);
if (key < 0)
{
perror("ftok()");
exit(1);
}
shmid = shmget(key, size, IPC_CREAT | 0666);
if (shmid < 0)
{
perror("shmget()");
exit(1);
}
shmp = shmat(shmid, NULL, 0);
if (shmp == NULL)
{
perror("shmat()");
exit(1);
}
*shmp = 0;
semp = (sem_t *)mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (semp == NULL)
{
perror("mmap()");
exit(1);
}
if (sem_init(semp, 1, 1) < 0)
{
perror("sem_init()");
exit(1);
}
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (pid == 0)
{
while (n--)
{
sem_wait(semp);
(*shmp)++;
sem_post(semp);
}
exit(0);
}
while (n--)
{
sem_wait(semp);
(*shmp)++;
sem_post(semp);
}
wait(NULL);
printf("%d\n",*shmp);
sem_destroy(semp);
shmdt(shmp);
munmap(semp, sizeof(sem_t));
exit(0);
}