进程间通信方式1——共享内存

el/2024/3/2 10:34:33

一、共享内存是什么?

共享内存允许两个或更多进程访问同一块内存,不同进程之间共享的内存通常为计算机中的同一段物理内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。进程可以将同一段物理内存连接到他们自己的地址空间中(通过虚拟地址映射),所有的进程都可以访问共享内存中的地址。

共享内存的优缺点:
原文链接:https://blog.csdn.net/d_guco/article/details/53524854

1.共享内存号称是最快的进程间通信方式。
2.共享内存适用于大数据量的传输,读取不等待写入,需要设置同步,可以用信号量来实现对共享内存同步访问控制。可以通过管道发送同步信号。管道适合传输小数据量。
3.通过名字知道它是基于内存的,所以他只能在同一主机上使用,如果我们要做分布式应用或者跨物理机通信,那么socket就是我们唯一的选择了。

二、书写代码时的可能出现的错误

  • 向共享内存中存放数据时,需在共享内存映射之后再存放数据,否则存放不成功

  • 存放数据时若出现段错误时,则可能是因为代码中出现了野指针

  • 若两个进程中开辟的共享内存空间不一致则报错:shmget: Invalid argument

三、代码例程

参考知乎了知乎上的代码例程

情景:创建两个进程,在 A 进程中创建一个共享内存,并向其写入数据(结构体形式进行数据传输 ),通过 B 进程从共享内存中读取数据

A写进程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>#define BUFSZ 100
struct Mem{int type ;char data[BUFSZ];};
int main(int argc, char *argv[])
{//struct Mem mem1;int shmid;int ret;key_t key;struct Mem *shmadd;//创建key值key = ftok("/dev/ppp", 2021);if(key == -1){perror("ftok");}//创建共享内存shmid = shmget(key, BUFSZ*sizeof(char)+sizeof(int), IPC_CREAT|0666);    if(shmid < 0){perror("shmget");exit(-1);}//映射shmadd = (struct Mem *)shmat(shmid, NULL, 0);if(shmadd < 0){perror("shmat");_exit(-1);}// 共享内存清空memset(shmadd, 0, sizeof(shmadd));	//拷贝数据至共享内存区printf("copy data to shared-memory\n");   //bzero(mem1.data, BUFSZ); // 共享内存清空(*shmadd).type = 1;strcpy((*shmadd).data, "how are you, lh\n");//拷贝数据至共享内存区//printf("copy data to shared-memory\n");//strcpy(shmadd, "how are you, lh\n");printf("type = [%d]\n", (*shmadd).type);printf("data = [%s]\n", (*shmadd).data);  return 0;
}

B读进程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>#define BUFSZ 100
typedef struct MemA{int type;char data[BUFSZ];
}MemA;
int main(int argc, char *argv[])
{int shmid;int ret;key_t key;MemA *shmadd;//创建key值key = ftok("/dev/ppp", 2021);if(key == -1){perror("ftok");}system("ipcs -m"); //查看共享内存//打开共享内存shmid = shmget(key, BUFSZ  +4, IPC_CREAT|0666);if(shmid < 0){printf("error");perror("shmget");exit(-1);}//映射shmadd = (MemA *)shmat(shmid, NULL, 0);if(shmadd < 0){perror("shmat");exit(-1);}//读共享内存区数据printf("type = [%d]\n", (*shmadd).type);printf("data = [%s]\n", (*shmadd).data);//分离共享内存和当前进程ret = shmdt(shmadd);if(ret < 0){perror("shmdt");exit(1);}else{printf("deleted shared-memory\n");}//删除共享内存shmctl(shmid, IPC_RMID, NULL);system("ipcs -m"); //查看共享内存return 0;
}

提示:
代码中所用到的函数详情可参考链接: https://cloud.tencent.com/developer/article/1527533.


总结

1.实现数据以结构体形式进行进程之间通信。
2.代码未提供同步机制


http://www.ngui.cc/el/3882151.html

相关文章

进程间通信方式2-------消息队列

目录 消息队列 最简单的消息队列的使用流程 消息队列(参考资料) https://www.cnblogs.com/wuyepeng/p/9748728.html https://blog.csdn.net/ljianhui/article/details/10287879 消息队列 什么是消息队列&#xff1f; 消息队列&#xff0c;Unix的通信机制之一&#xff0c;可以…

opencv库 arm-linux交叉编译并移植

目录 静态链接库与动态链接库 opencv arm-linux交叉编译并移植 动态链接库与动态链接库 参考网址&#xff1a;https://www.jianshu.com/p/dbe848e4ad0d多个文件生成动态/静态库的用法&#xff1a; 动态库&#xff1a; 1.gcc -fPIC -shared xxx1.c xxx2.c xxx3.c -o libxxx…

列表中的一些命令

如何取出列表中第一个和最后一个元素 切片 1 names=["Xieningxuan","Huanglongjian","Changbingbing","Lifanlin","Fanlong","Zhangchi"] 2 print(names[0]) #列表中是第一个元素的位置是0, 也就是在列表中是…

八种数据类型详解——int篇

整数型在java中整数形式有四种表示形式: byte 1字节 -128————127 short 2字节 int 4字节 2147483647是int最大值,超了就用long long 8字节 最常用的是int 1字节=8比特 (8个二进制位) 在java 在任何情况下整数型的“字面量”默认被当作int类型处理 如果希望该“整数形…

textarea标签使用placeholder属性添加提示文字,页面却不显示

1.原因&#xff1a; 标签之间有空格 2.正确写法及错误写法&#xff1a; ①正确&#xff1a; <textarea type"text" name"message" placeholder"请输入留言内容"></textarea> ②错误&#xff1a; 2.1<textarea type"te…

微信小程序换行符、hidden属性、图片高度、背景图不显示问题

微信小程序问题总结 1. 换行符\n 1.1 微信小程序的换行符为\n,只能在text标签中使用&#xff0c;才能进行换行 1.2 当后端返回数据中存在换行符\n&#xff0c;并且在text标签中仍不进行换行显示&#xff0c;&#xff08;原因是后端返回的\n被转译成了字符串无法识别为换行符&a…

MatLab 2016b下载资源

MatLab 2016b下载资源 百度网盘链接: https://pan.baidu.com/s/1cc_qWaiLWl7O6e0O-xZjpg 提取码&#xff1a;6yei

并发控制(笔记)

并发控制 在单处理机系统中&#xff0c;事务的并发执行实际上是这些并行的事务的并行操作轮流交叉执行。 并发控制概述 事务是并发控制的基本单位 但是并发操作会出现以下一些问题。 1.丢失修改 2.不可重复读 3.读脏数据 &#xff08;与数据库内容不一致&#xff09; …

数据库恢复技术(笔记)

数据库恢复技术 1.事务 所谓事务是用户定义的一个数据库操作序列&#xff0c;这些操作要全做&#xff0c;要不全都不做&#xff0c;是一个不可分割的工作单位。 事务通常以BEGIN TRANSACTION开始&#xff0c;以commit或者是rollback结束&#xff0c; commit 表示提交&#xf…

查找的基本概念(笔记)

1.查找表 查找表是由同一类型的数据元素&#xff08;或记录&#xff09;构成的集合。 2.关键字 关键字是数据元素&#xff08;或记录&#xff09;中某个数据项的值。用它可以标识一个数据元素&#xff08;或记录&#xff09;。若此关键字可以唯一标识一个记录&#xff0c;则称此…