linux进程利用mmap映射区通信

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值