Linux系统编程 day6 进程间通信mmap

父子共享的信息:文件描述符,mmap建立的共享映射区(MAP_SHARED)

mmap父子间进程通信

var的时候 :读时共享,写时复制

父进程先创建映射区,指定共享MAP_SHARED权限 , fork创建子进程。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<sys/wait.h>
int var = 100;
int main(int argc , char *argv[])
{
    int fd;
    pid_t pid;
    int *p;
    fd = open("text" , O_RDWR|O_CREAT|O_TRUNC , 0644);
    if(fd == -1){
        perror("open error");
        exit(1);
    }

    ftruncate(fd , 4);
    p = (int*)mmap(NULL, 4 , PROT_READ|PROT_WRITE , MAP_SHARED , fd , 0);
    if(p == MAP_FAILED){
        perror("mmap error");
        exit(1);
    }
    pid = fork();
    if(pid == 0){
        *p = 2000;   //写共享内存
        var = 1000;  
        printf("I am child,mypid:%d , *p = %d , var = %d\n" , getpid() , *p ,var);
    }else
    {
        sleep(1);
        printf("I am parent , *p = %d , var = %d\n" , *p , var);
        wait(NULL);

        int ret = munmap(p , 4);
        if(ret == -1){
            perror("munmap error");
            exit(1);
        }
    }
    return 0 ;
}

mmap无血缘关系进程间通信(重点)

两个进程打开同一个文件,创建映射区,指定flags为MAP_SHARED,一个进程写入一个进程读出。效率应该是最高的。 

为什么会映射到同一块内存上,借用GPT:即使两个没有血缘关系(即非父子关系)的进程,分别 open() 同一个文件,然后使用 mmap() 映射这同一个文件,得到的指针 p(虚拟地址)**可能不同,但它们最终指向的是同一块 物理内存页,因为 mmap 的核心是文件映射到物理页帧,多个进程映射相同文件内容,就映射到了同一块物理内存。

写端:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<sys/wait.h>


struct student{
    int id ;
    char name[256];
    int age;
};

int main(int argc , char *argv[])
{
    struct student stu = {1 , "xiaoming" , 19};
    int fd;
    int *p;
    fd = open("textw" , O_RDWR|O_CREAT|O_TRUNC , 0644);
    ftruncate(fd , sizeof(stu));
    printf("fdwrite:%d\n",fd);
    p = mmap(NULL, sizeof(stu) , PROT_READ|PROT_WRITE , MAP_SHARED , fd , 0);
    if(p == MAP_FAILED){
        perror("mmap error");
        exit(1);
    }
    close(fd);
    while(1){
        sleep(1);
        memcpy(p ,&stu ,sizeof(stu));
        stu.id++;
    }
    munmap(p , sizeof(stu));
    return 0;
}

读端:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<sys/wait.h>


struct student{
    int id ;
    char name[256];
    int age;
};

int main(int argc , char *argv[])
{
    struct student stu;
    int fd;
    struct student *p;
    fd = open("textw" , O_RDWR);
    printf("fd read: %d\n" , fd);
    p = mmap(NULL, sizeof(stu) , PROT_READ|PROT_WRITE , MAP_SHARED , fd , 0);
    if(p == MAP_FAILED){
        perror("mmap error");
        exit(1);
    }
    close(fd);
    while(1){
        printf("id:%d , name:%s , age:%d\n" , p->id , p->name , p->age);
        sleep(1);
    }
    munmap(p , sizeof(stu));
    return 0;
}

注意:无血缘关系进程间通信。FIFO:数据只能一次读取

mmap:数据可以重复读取。

匿名映射(了解)

void* mmap(NULL , size , PROT_READ|PROT_WRITE , MAP_SHARED|MAP_ANON , -1 ,0);

size: 可以随便写
flags:需要写MAP_ANON
fd : -1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值