IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Linux系统编程之共享存储映射 -> 正文阅读

[C++知识库]Linux系统编程之共享存储映射

文件进程间通讯

在这里插入图片描述
open函数
在这里插入图片描述
在这里插入图片描述

 /*
 *  @file           fork_shared_fd.c
 *  @brief          父子进程共享打开的文件描述符,使用文件完成进程间通讯
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */

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

int main(void)
{
        int fd1;
        int fd2;
        pid_t pid;
        char buf[1024];
        char *str = "-------test for shared fd in parent child process------\n";
        int len;

        pid = fork();
        if(pid < 0)
        {
                perror("fork error");
                exit(1);
        }
        else if(pid == 0)
        {
                fd1 = open("test.txt", O_RDWR);
                if(fd1 < 0)
                {
                        perror("open error");
                        exit(1);
                }
                write(fd1, str, strlen(str));
                printf("child wrote over...\n");
        }
        else
    	{
                fd2 = open("test.txt", O_RDWR);
                if(fd2 < 0)
                {
                        perror("open error");
                        exit(1);
                }
                sleep(1);               //保证子进程写入数据
                len = read(fd2, buf, sizeof(buf));
                write(STDOUT_FILENO, buf, len);
                wait(NULL);
        }

        return 0;
}

在这里插入图片描述

存储映射I/O

在这里插入图片描述在这里插入图片描述

mmap创建映射区

在这里插入图片描述
mmap函数munmap函数
在这里插入图片描述
在这里插入图片描述
ftruncate函数
在这里插入图片描述

/*
 *  @file           mmap_creat.c
 *  @brief          用mmap函数创建映射区
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */

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

int main(void)
{
        int len;
        int ret;
        char *p = NULL;
        int fd;

        fd = open("mmaptest.txt", O_CREAT|O_RDWR, 0644);
        if(fd < 0)
        {
                perror("open error");
                exit(1);
        }

        len = ftruncate(fd, 5);
        if(len == -1)
        {
                perror("ftruncate error");
                exit(1);
        }

        p = mmap(NULL, 5, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        if(p == MAP_FAILED)
        {
                perror("mmap error");
                exit(1);
        }

        strcpy(p, "abc\n");             //写数据

        ret = munmap(p, 5);
        if(ret == -1)
        {
                perror("munmap error");
                exit(1);
        }

        close(fd);

        return 0;
}
         

通过映射区的指针来把数据写入文件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

mmap父子进程通讯

在这里插入图片描述
目录项的概念
在这里插入图片描述

/*
 *  @file           fork_mmap.c
 *  @brief          mmap父子进程间通讯,父进程创建映射区,然后fork子进程,
                    子进程修改映射区内容,最后,父进程读取映射区内容,
                    查验是否共享
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */

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

int var = 100;

int main(void)
{
        int *p;
        pid_t pid;
        int fd;
        int ret;

        fd = open("fork_mmap.txt", O_RDWR|O_CREAT|O_TRUNC, 0644);
        if(fd < 0)
        {
                perror("open error");
                exit(1);
        }

        unlink("fork_mmap.txt");                //删除临时文件目录项,使之具备被释放条件

        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);
        }
        close(fd);

        pid = fork();
        if(pid == -1)
        {
                perror("fork error");
                exit(1);
        }
        else if(pid == 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);

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

        return 0;
}

在这里插入图片描述

匿名映射

在这里插入图片描述

用宏创建匿名映射

这个宏MAP_ANONYMOUS只能在linux下用

/*
 *  @file           anon.c
 *  @brief          用宏MAP_ANONYMOUS创建匿名映射
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */

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

int var = 100;

int main(void)
{
        int *p;
        pid_t pid;
        int ret;

        p = (int *)mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
        if(p == MAP_FAILED)
        {
                perror("mmap error");
                exit(1);
        }

        pid = fork();
        if(pid == 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);

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

        return 0;
}

在这里插入图片描述

用/dev/zero创建匿名映射

在这里插入图片描述

/*
 *  @file           anon1.c
 *  @brief          用/dev/zero创建匿名映射
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */

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

int var = 100;

int main(void)
{
        int *p;
        pid_t pid;
        int fd;
        int ret;

        fd = open("/dev/zero", O_RDWR);

        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("child, *p = %d, var = %d\n", *p, var);
        }
        else
        {
                sleep(1);
                printf("parent, *p = %d, var = %d\n", *p, var);
                wait(NULL);

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

        return 0;
}

在这里插入图片描述

mmap无血缘关系进程间通讯

在这里插入图片描述

/*
 *  @file           mmap_w.c
 *  @brief          mmap无血缘关系之间通讯写入数据的一方
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */

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

struct STU
{
        int id;
        char name[20];
        char sex;
};

void sys_err(char *str)
{
        perror(str);
        exit(1);
}

int main(int argc, char *argv[])
{
        int fd;
        struct STU student = {18, "beipi", 'm'};
        char *mm;

        if(argc < 2)
        {
                printf("./a.out file_shared\n");
                exit(-1);
        }

        fd = open(argv[1], O_RDWR|O_CREAT, 0664);
        ftruncate(fd, sizeof(student));

        mm = mmap(NULL, sizeof(student), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        if(mm == MAP_FAILED)
        {
                sys_err("mmap");
        }
        close(fd);

        while(1)
        {
                memcpy(mm, &student, sizeof(student));
                student.id++;
                sleep(1);
        }
        munmap(mm, sizeof(student));
}

/*
 *  @file           mmap_r.c
 *  @brief          mmap无血缘关系之间通讯读的一方
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */


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

struct STU
{
        int id;
        char name[20];
        char sex;
};

void sys_err(char *str)
{
        perror(str);
        exit(-1);
}

int main(int argc, char *argv[])
{
        int fd;
        struct STU student;
        struct STU *mm;

        if(argc < 2)
        {
                printf("./a.out file_shared\n");
                exit(-1);
        }

        fd = open(argv[1], O_RDONLY);
        if(fd == -1)
        {
                sys_err("open error");
        }

        mm = mmap(NULL, sizeof(student), PROT_READ, MAP_SHARED, fd, 0);
        if(mm == MAP_FAILED)
        {
                sys_err("mmap error");
        }
        close(fd);

        while(1)
        {
                printf("id = %d\tname = %s\tsex = %c\n", mm->id, mm->name, mm->sex);
                sleep(2);
        }
        munmap(mm, sizeof(student));

        return 0;
}

在这里插入图片描述

文件无血缘关系进程间通讯

/*
 *  @file           file_w.c
 *  @brief          文件无血缘关系之间通讯写的一方
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

#define N 5

int main(void)
{
        char buf[1024];
        char *str = "------------secesuss------------\n";
        int ret;
        int fd;

        fd = open("file_test.txt", O_RDWR|O_TRUNC|O_CREAT, 0664);

        write(fd, str, strlen(str));
        printf("file_w write innto file_test.txt finish\n");

        sleep(N);

        lseek(fd, 0, SEEK_SET);
        ret = read(fd, buf, sizeof(buf));
        ret = write(STDOUT_FILENO, buf,ret);

        if(ret == -1)
        {
                perror("write second error");
                exit(1);
        }

        close(fd);

        return 0;
}

/*
 *  @file           file_r.c
 *  @brief          文件无血缘关系之间通讯写的一方
 *  @version 1.1    无
 *  @author         北豼
 *  @date           2022年5月10日
 */

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>

int main(void)
{
        char buf[1024];
        char *str = "--------------------file_r write secesuss-----------\n";
        int ret;
        int fd;

        sleep(2);               //睡眠2秒,保证file_w.txt将数据写入file_test.txt文件

        fd = open("file_test.txt", O_RDWR);
        ret = read(fd, buf, sizeof(buf));
        write(STDOUT_FILENO, buf, ret);

        write(fd, str, strlen(str));
        printf("file_r read/write finish\n");

        close(fd);

        return 0;
}


在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-13 11:37:20  更:2022-05-13 11:38:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 21:01:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码