共享内存用于进程间通信

共享内存在父子进程间通信

示例

/*
 * function: 演示使用mmap()函数实现使用共享映射区完成父子进程间通信
 *
 * 2020-12-07
 */

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

int main(int argc, char *argv[])
{
    // 打开一个文件
    int fd = open("tmp", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (fd == -1)
    {
        perror("open faild");
        exit(1);
    }

    // 扩展文件大小, 需要打开的文件具有可写属性
    if (ftruncate(fd, 20) == -1)
    {
        perror("ftruncate faild");
        exit(1);
    }

    // 获取文件大小
    off_t n = lseek(fd, 0, SEEK_END);
    if (n == -1)
    {
        perror("lseek faild");
        exit(1);
    }

    // 将文件映射到共享内存中
    char *p = NULL;
    p = (char *)mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (p == MAP_FAILED)
    {
        perror("mmap failed");
        exit(1);
    }

    pid_t pid = 0;
    pid = fork();
    if (pid == -1)
    {
        perror("fork faild");
        exit(1);
    }
    else if (pid == 0) // 子进程
    {
        strcpy(p, "hello mmap");
        printf("子进程完成写共享内存操作\n");
    }
    else    // 父进程
    {
        sleep(1);   // 睡眠一秒,让子进程完成写共享内存操作
        printf("%s\n", p);
        printf("父进程完成读共享内存操作\n");
    }

    // 系统调用删除指定地址范围的映射
    if(munmap(p, n) == -1)
    {
        perror("mumap faild");
        exit(1);
    }

    close(fd);

    return 0;
}

mmap

共享内存在无血缘关系进程间通信

写端示例

/*
 * function: 演示使用mmap()函数实现使用共享映射区完成无血缘关系进程间通信
 *           此进程为写端
 *
 * 2020-12-07
 */

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

int main(int argc, char *argv[])
{
    // 打开一个文件
    int fd = open("tmp", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) 
    {   
        perror("open faild");
        exit(1);
    }   

    // 扩展文件大小, 需要打开的文件具有可写属性
    if (ftruncate(fd, 20) == -1) 
    {   
        perror("ftruncate faild");
        exit(1);
    }   

    // 获取文件大小
    off_t n = lseek(fd, 0, SEEK_END);
    if (n == -1) 
    {   
        perror("lseek faild");
        exit(1);
    }

    // 将文件映射到共享内存中
    char *p = NULL;
    p = (char *)mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (p == MAP_FAILED)
    {
        perror("mmap failed");
        exit(1);
    }

    // 写共享内存
    strcpy(p, "hello world");

    printf("写共享内存完成\n");

    // 系统调用删除指定地址范围的映射
    if(munmap(p, n) == -1)
    {
        perror("mumap faild");
        exit(1);
    }

    close(fd);

    return 0;
}

读端示例

/*
 * function: 演示使用mmap()函数实现使用共享映射区完成无血缘关系进程间通信
 *           此进程为读端
 * 2020-12-07
 */

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

int main(int argc, char *argv[])
{
    // 打开一个文件
    int fd = open("tmp", O_RDWR);
    if (fd == -1) 
    {   
        perror("open faild");
        exit(1);
    }   

    // 获取文件大小
    off_t n = lseek(fd, 0, SEEK_END);
    if (n == -1) 
    {   
        perror("lseek faild");
        exit(1);
    }   

    // 将文件映射到共享内存中
    char *p = NULL;
    p = (char *)mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if (p == MAP_FAILED)
    {
        perror("mmap failed");
        exit(1);
    }

    // 读共享内存
    printf("%s\n", p);

    printf("读共享内存完成\n");

    // 系统调用删除指定地址范围的映射
    if(munmap(p, n) == -1)
    {
        perror("mumap faild");
        exit(1);
    }

    close(fd);

    return 0;
}

mmap_wr

匿名映射

只能用于有血缘关系进程间通信

Linux

通过mmap函数第4个参数,使用MAP_ANONYMOUS (或 MAP_ANON)完成匿名映射。

示例

/*
 * function: 演示使用mmap()函数实现匿名映射完成父子进程间通信
 *
 * 2020-12-08
 */

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

int main(int argc, char *argv[])
{
    // 将文件映射到共享内存中
    char *p = NULL;
    size_t n = 20;
    p = (char *)mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); 
    if (p == MAP_FAILED)
    {   
        perror("mmap failed");
        exit(1);
    }   

    pid_t pid = 0;
    pid = fork();
    if (pid == -1) 
    {   
        perror("fork faild");
        exit(1);
    }   
    else if (pid == 0) // 子进程
    {   
        strcpy(p, "hello mmap_anon");
        printf("子进程完成写共享内存操作(匿名映射)\n");
    }
    else    // 父进程
    {
        sleep(1);   // 睡眠一秒,让子进程完成写共享内存操作
        printf("%s\n", p);
        printf("父进程完成读共享内存操作(匿名映射)\n");
    }

    // 系统调用删除指定地址范围的映射
    if(munmap(p, n) == -1)
    {
        perror("mumap faild");
        exit(1);
    }

    return 0;
}

mmap_anon

类UNIX

MAP_ANONYMOUS 和 MAP_ANON 这两个宏是 Linux 操作系统特有的宏。在类 Unix 系统中如无该宏定义,可通过/dev/zero文件完成匿名映射。

示例

/*
 * function: 演示使用mmap()函数实现使用共享映射区完成父子进程间通信
 *
 * 2020-12-07
 */

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

int main(int argc, char *argv[])
{
    // 打开一个文件
    int fd = open("/dev/zero", O_RDWR);
    if (fd == -1) 
    {   
        perror("open faild");
        exit(1);
    }   

    // 将文件映射到共享内存中
    char *p = NULL;
    size_t n = 10; 
    p = (char *)mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if (p == MAP_FAILED)
    {   
        perror("mmap failed");
        exit(1);
    }   
    
    pid_t pid = 0;
    pid = fork();
    if (pid == -1)
    {
        perror("fork faild");
        exit(1);
    }
    else if (pid == 0) // 子进程
    {
        strcpy(p, "hello mmap_anon_unix");
        printf("子进程完成写共享内存操作(匿名映射)\n");
    }
    else    // 父进程
    {
        sleep(1);   // 睡眠一秒,让子进程完成写共享内存操作
        printf("%s\n", p);
        printf("父进程完成读共享内存操作(匿名映射)\n");
    }

    // 系统调用删除指定地址范围的映射
    if(munmap(p, n) == -1)
    {
        perror("mumap faild");
        exit(1);
    }

    close(fd);

    return 0;
}

mmap_anon_unix

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值