linux进程利用mmap映射区通信

来源:互联网 发布:iphone7plus软件铃声 编辑:程序博客网 时间:2024/05/18 11:47

1,建立共享映射区,将磁盘文件映射到内核区,并返回映射地址

include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>#include<string.h>#include<sys/mman.h>int main(){  pid_t pid;  pid = open("test.c", O_CREAT | O_RDWR, 0644);//打开文件  if(pid == -1)  {    perror("open fail");    exit(1);  }  ftruncate(pid, 4);//文件大小为4  char* p = NULL;  p = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, pid, 0);//将文件映射到内核  if(p == MAP_FAILED)//p为映射区首地址  {    perror("MAP failed");       exit(1);  }  strcpy(p,"abc");//共享映射区写入数据  munmap(p, 4);//  close(pid);  return 0;}

父子进程通过mmap共享映射区进行通信

include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>#include<string.h>#include<sys/mman.h>#include<sys/wait.h>int var = 10;int main(){  pid_t pid;  pid = open("temp", O_CREAT | O_RDWR, 0644);  if(pid == -1)  {    perror("open fail");    exit(1);  }  ftruncate(pid, 4);  unlink("temp");//删除临时文件目录项,使之具备被释放条件  int* p;   p = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, pid, 0);  if(p == MAP_FAILED)  {    perror("MAP failed");    exit(1);  }  close(pid);//映射区建立完毕,可以提前关闭文件  pid_t q;  q = fork();  if(q == -1)  {    perror("create fail");    exit(1);  }  else if(q == 0)  {    *p = 2000;    var = 1000;    printf("*p = %d, var = %d\n", *p, var);  }  else  {    sleep(1);    printf("*p = %d, var = %d\n", *p, var);    wait(NULL);    munmap(p, 4);//释放映射区  }  return 0;}

2,匿名映射区
使用映射区来完成文件读写操作十分方便,但是每次创建映射区都要依赖一个文件才能实现,比较麻烦。可以直接用匿名映射区来代替。

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>#include<string.h>#include<sys/mman.h>#include<sys/wait.h>int var = 10;int main(){  int* p;  p = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);//创建匿名映射区  if(p == MAP_FAILED)  {    perror("MAP failed");    exit(1);  }  pid_t q;  q = fork();  if(q == -1)  {    perror("create fail");    exit(1);  }  else if(q == 0)  {    *p = 2000;    var = 1000;    printf("child, *p = %d, var = %d\n", *p, var);  }  else  {    sleep(1);    printf("parent, *p = %d, var = %d\n", *p, var);    wait(NULL);    munmap(p, 4);  }  return 0;}

3,无血缘关系的进程间利用mmap进行通信
mmap_w.c
不断更改写入

#include<stdio.h>#include<stdlib.h>#include<fcntl.h>#include<sys/mman.h>#include<unistd.h>#include<string.h>struct stu{  int id;  char name[20];  char sex;};void sys_err(char* err){  perror(err);  exit(-1);}int main(int argc, char* argv[]){   if(argc < 2)  {        printf("./mmap_w file_share");    exit(1);  }  int fd = open(argv[1], O_CREAT | O_TRUNC | O_RDWR, 0644);  if(fd == -1)    sys_err("open file fail");  struct stu student = {18, "xiaoming", 'm'};  ftruncate(fd, sizeof(student));  struct stu* mm;  mm = mmap(NULL, sizeof(student), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);  if(mm == MAP_FAILED)    sys_err("mmap fail");  close(fd);  while(1)  {    memcpy(mm, &student, sizeof(student));    student.id++;    sleep(5);  }  munmap(mm, sizeof(student));  return 0;}                       

不断读出 mmap_r.c

include<stdio.h>#include<stdlib.h>#include<fcntl.h>#include<sys/mman.h>#include<unistd.h>#include<string.h>struct stu{  int id;  char name[20];  char sex;};void sys_err(char* err){  perror(err);  exit(-1);}int main(int argc, char* argv[]){  if(argc < 2)  {  printf("./mmap_w file_share\n");    exit(2);  }  int fd = open(argv[1], O_RDONLY);  if(fd == -1)    sys_err("open file fail");  struct stu student;  struct stu* mm;  mm = mmap(NULL, sizeof(student), PROT_READ, MAP_SHARED, fd, 0);  if(mm == MAP_FAILED)    sys_err("mmap fail");  close(fd);  while(1)  {    printf("id = %d, name = %s, sex = %c\n", mm->id, mm->name, mm->sex);    sleep(2);  }  munmmap(mm, sizeof(student));  return 0;}