linux 进程通信子mmap

  1. mmap 文件–内存映射
    函数原型
 #include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
参数介绍:
add 传 NULL
length 映射区的长度
protPROT_READ 可读PROT_WRITE可写
flagsMAP_SHARED 共享的,对内存的修改会影响源文件MAP_PRIVATE 私有的
fd 文件描述符,open一个文件
offset 偏移量返回值:成功:返回可用内存的首地址,失败:返回MAP_FAILED

释放映射区

 int munmap(void *addr, size_t length);
参数:
addr 传mmap的返回值
length mmap创建的长度
返回值:成功返回0失败返回-1

#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);

这两个函数可以根据文件描述符,或者是文件名,修改文件的大小(字节)

  1. mmap函数注意事项
    在这里插入图片描述
  2. 使用mmap进行父子进程之间的通信
    代码示例:
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>int main(int argc, char *argv[]) {if(argc !=2) {printf("./a.out filename1");return -1;}int fd = open(argv[1], O_RDWR|O_CREAT, 0666);ftruncate(fd, 4);int *mem = mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd , 0);pid_t pid = fork();if(pid == 0) {// son*mem = 100;sleep(3);printf("son mem = %d\n", *mem);} else if(pid>0){//fathersleep(1);printf("father mem = %d\n", *mem);*mem = 2;wait(NULL);}munmap(mem, 4);close(fd);return 0;
}
  1. 使用mmap,让无血缘关系的进程之间进行通信代码案例:

写端:

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
typedef struct _student
{int sid;char sname[20];
}Student;
int main(int argc, char *argv[]) {if(argc!=2) {printf("./a.out filename\n");return -1;}int fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);int length = sizeof(Student);ftruncate(fd, length);Student *stu = mmap(NULL, length, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);int num = 0;while (1){stu->sid = num++;sprintf(stu->sname, "mynames_x%d", num); sleep(1);}munmap(stu, length);close(fd);return 0;
}

读端:

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
typedef struct _student
{int sid;char sname[20];
}Student;
int main(int argc, char *argv[]) {if(argc!=2) {printf("./a.out filename\n");return -1;}int fd = open(argv[1], O_RDONLY, 0666);int length = sizeof(Student);ftruncate(fd, length);Student *stu = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);int num = 0;while (1){printf("read sid= %d\n", stu->sid);printf("%s\n", stu->sname);sleep(1);}munmap(stu, length);close(fd);return 0;
}
  1. 利用mmap使用4个进程对一个文件进行拷贝
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>int main(int argc, char*argv[]) {if(argc!=3) {printf("./a.out filename_src filename_desc \n");return -1;}int srcfd = open(argv[1], O_RDWR);int desfd = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, 0666);struct stat sb;stat(argv[1], &sb);int len = sb.st_size;truncate(argv[2], len);char *memsrc = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, srcfd, 0);if(memsrc == MAP_FAILED) {printf("mmaperror1\n");return -1;}char *memdes = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, desfd, 0);if(memdes == MAP_FAILED) {printf("mmaperror2\n");return -1;}int i=0;int one_size = len / 4;int remainder_size = len % 4;pid_t pid;for(; i<5; ++i) {pid = fork();if(pid==0) {break;}}if (i<5) {if(i==4) {memcpy(memdes + i*one_size, memsrc + i*one_size, one_size + remainder_size);} else {memcpy(memdes + i*one_size, memsrc + i*one_size, one_size);}} else {wait(NULL);printf("cp file end\n");}int unmemsrc = munmap(memsrc, len);int unmemdes = munmap(memdes, len);printf("%d unmemsrc --------- %d\n", getpid(), unmemsrc);printf("%d unmemdes %d\n", getpid(), unmemdes);close(desfd);close(srcfd); return 0;
}

ps:疑惑的地方 上面这端代码最后释放内存的这一部分,相当于多个进程对同一块内存进行了重复释放吧? 是这样吗?
ps2:疑惑的地方 mmap通过文件映射的内存位于哪块内存区???

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux信号学习02

未决信号集与阻塞信号集(信号屏蔽字) 阻塞信号集&#xff1a; 将某些信号加入集合&#xff0c;对他们设置屏蔽&#xff0c;当屏蔽x信号后&#xff0c;再收到该信号&#xff0c;该信号的处理将推后(解除屏蔽后) 未决信号集&#xff1a; a. 信号产生&#xff0c;未决信号集中描述…

软件工程学习笔记《三》代码优化和性能测试

文章目录软件工程学习笔记目录如何在开源社区提问&#xff1f;代码审查代码优化运行结果参数解释代码优化原则对常见的数据结构排序算法进行测试关于冒泡排序优化的探讨结果软件工程学习笔记目录 [https://blog.csdn.net/csdn_kou/article/details/83754356] 如何在开源社区提…

linux信号捕捉

信号捕捉&#xff0c;防止进程意外死亡 signal函数 man signal #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);参数介绍&#xff1b; signum 要捕捉的信号 handler 要执行的捕捉函数指针&#xff0c…

软件工程学习笔记《四》需求分析

文章目录软件工程学习笔记《目录》需求工程师当代的需求工程师需要具备的能力当代的需求工程师需要努力的方向当代的需求工程师需要注意的错误需求的定义需求目标需求分析的实质需求分析的关键应该涵盖的内容&#xff1f;需求规约&#xff08;作为较客观的参照&#xff09;单个…

linux守护进程

先了解 linux系统中 会话的概念 会话是进程组的更高一级&#xff0c;多个进程组对应一个会话。 会话是一个或多个进程组的集合 创建一个会话需要注意以下5点事项&#xff1a; a. 调用进程不能是进程组组长&#xff0c; 该进程变成新会话首进程&#xff08;session header&#…

linux 线程学习初步01

线程的概念 进程与线程内核实现 通过函数clone实现的 ps -Lf pidLinux内核线程实现原理 同一个进程下的线程&#xff0c;共享该进程的内存区&#xff0c; 但是只有stack区域不共享。 线程共享资源 a.文件描述符表 b.每种信号的处理方式 c.当前工作目录 d.用户id和组id 线程…

python的文件基本操作和文件指针

读写模式的基本操作 https://www.cnblogs.com/c-x-m/articles/7756498.html r,w,a r只读模式【默认模式&#xff0c;文件必须存在&#xff0c;不存在则抛出异常】w只写模式【不可读&#xff1b;不存在则创建&#xff1b;存在则清空内容】a之追加写模式【不可读&#xff1b;不…

HTTP菜鸟教程速查手册

HTTP协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是因特网上应用最为广泛的一种网络传输协议&#xff0c;所有的WWW文件都必须遵守这个标准。 HTTP是一个基于TCP/IP通信协议来传递数据&#xff08;HTML 文件, 图片文件, 查询结果等&am…

mysql学习笔记01-创建数据库

创建数据库&#xff1a; 校验规则&#xff1a;是指表的排序规则和查询时候的规则 utf8_general_ci 支持中文&#xff0c; 且不区分大小写 utf8_bin 支持中文&#xff0c; 区分大小写 比如&#xff1a; create database db3 character set utf8 collate utf8_general_ci; &…

python的Web编程

首先看一下效果 完整代码 import socket from multiprocessing import ProcessHTML_ROOT_DIR ""def handle_client(client_socket):request_data client_socket.recv(1024)print("request data:", request_data)response_start_line "HTTP/1.0 20…

mysql 学习笔记 02创建表

表结构的创建 比如&#xff1a; create table userinfo (id int unsigned comment id号name varchar(60) comment 用户名password char(32),birthday date ) character set utf8 engine MyISAM;comment 表示注释的意思 不同的存储引擎&#xff0c;创建的表的文件不一样

mysql 学习笔记03 常用数据类型

数值类型&#xff1a; a. 整数类型&#xff1a; 注意事项&#xff1a; 举例&#xff1a;某个整型字段 &#xff0c;不为空&#xff0c;且有默认值 create table test (age int unisigned not null default 1);zerofill的使用 b. bit类型的使用 c.小数类型 小数类型占用…

VMware的虚拟机连不上网

1.如果你发现在VMware下运行的虚拟机无法连接网络&#xff0c;那下面的方法也许可以帮 到你。&#xff08;前提是你的物理网络是通的&#xff09; 第一步&#xff1a;在VMware界面下 单击“编辑“→”虚拟网络编辑器” 第二步&#xff1a;单击”更改设置” 获取权限&#xff…

python三国演义人物出场统计

完整代码 开源代码 统计三国演义人物高频次数 #!/usr/bin/env python # codingutf-8 #e10.4CalThreeKingdoms.py import jieba excludes {"来到","人马","领兵","将军","却说","荆州","二人","…

mysql 学习笔记03修改表以及其他操作

首先创建一张表 在现有表的结构上增加字段 alter table users add image varchar(100) not null defalut comment 图片路径;修改某个字段的长度 alter table users modify job vachar(60) not null comment 工作;删除某个字段 删除sex这个字段 alter table users drop se…

mysql 学习笔记04 insert与update语句

1.插入数据 注意事项&#xff1a; 字符和日期类型&#xff0c; 要用 单引号 括起来 insert into (), (), () 例如&#xff1a; insert into goods values(1, abc, 2.2), (2, def, 3.3);这种形式添加多条记录 insert 语句&#xff0c;如果没有指定字段名&#xff0c;则values …

PyCharm怎么关闭端口,解决端口占用问题

在进行web开发遇到这个问题&#xff01;

mysql 笔记05 select语句以及条件语句的使用

select语句 过滤重复语句&#xff08;distinct&#xff09; 举例&#xff1a; 查询学生的总分 select name, math English China as 总分 from students;在姓赵的学生总分基础上&#xff0c; 增加60%&#xff0c; select name, round((math English China) * 1.6, 2) as …

mysql 学习笔记05 统计函数的相关使用

合计函数count&#xff0c; 统计多少条记录 统计共有多少学生 select count(*) from students;查询数学成绩大于等于90的学生数量 select count(*) from students where math > 90;查询总分超过235分的学生的数量 select count(*) from students where (English math Ch…