技术专栏
Linux 基于共享内存的进程通信方式
1概述
共享内存是System V版本的最后一个进程间通信方式,也是进程间通信最简单的方式之一。共享内存允许两个或多个进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。
2特点
1.共享内存是一种进程间共享数据速度最快的方法。
一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
2.使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥。
一个进程正在向共享内存区域写数据,则在它做完这一步操作前,别的进程不应当去读、写这些数据。
3常用函数
3.1创建共享内存
1.头文件:
#include <sys/ipc.h>
#include <sys/shm.h>
2.函数原型:
int shmget(key_t key, size_t size,int shmflg);
3.功能:
创建或打开一块共享内存区。
4.参数说明:
key:进程间通信键值,ftok() 的返回值。
size:该共享存储段的长度(字节)。
shmflg:标识函数的行为及共享内存的权限,其取值如下:
IPC_CREAT:如果不存在就创建。
IPC_EXCL:如果已经存在则返回失败。
位或权限位:共享内存位或权限位后可以设置共享内存的访问权限,格式和 open() 函数的 mode_t 一样(open() 的使用请点此链接),但可执行权限未使用。
5.返回值:
成功:共享内存标识符。
失败:-1。
6.实例代码:
#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 1024
int main(int argc, char *argv[])
{
int shmid;
key_t key;
key = ftok("./", 2015);
if(key == -1)
{
perror("ftok");
}
//创建共享内存
shmid = shmget(key, BUFSZ, IPC_CREAT|0666);
if(shmid < 0)
{
perror("shmget");
exit(-1);
}
return 0;
}
3.2共享内存映射
1.头文件:
#include <sys/types.h>
#include <sys/shm.h>
2.函数原型:
void *shmat(int shmid, const void *shmaddr, int shmflg);
3.功能:
将一个共享内存段映射到调用进程的数据段中。简单来理解,让进程和共享内存建立一种联系,让进程某个指针指向此共享内存。
4.参数介绍:
shmid:共享内存标识符,shmget() 的返回值。
shmaddr:共享内存映射地址(若为 NULL 则由系统自动指定),推荐使用 NULL。
shmflg:共享内存段的访问权限和映射条件( 通常为 0 ),具体取值如下:
0:共享内存具有可读可写权限。
SHM_RDONLY:只读。
SHM_RND:(shmaddr 非空时才有效)
5.返回值:
成功:共享内存段映射地址( 相当于这个指针就指向此共享内存 )
失败:-1
3.3解除共享内存映射
1.头文件:
#include <sys/types.h>
#include <sys/shm.h>
2.函数原型:
int shmdt(const void *shmaddr);
3.功能:
将共享内存和当前进程分离( 仅仅是断开联系并不删除共享内存,相当于让之前的指向此共享内存的指针,不再指向)。
4.参数介绍:
shmaddr:共享内存映射地址。
5.返回值:
成功:0
失败:-1
3.4共享内存控制
1.头文件:
#include <sys/ipc.h>
#include <sys/shm.h>
2.函数原型:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
3.功能:
共享内存属性的控制。
4.参数介绍:
shmid:共享内存标识符。
cmd:函数功能的控制,其取值如下:
IPC_RMID:删除。(常用)
IPC_SET:设置 shmid_ds 参数,相当于把共享内存原来的属性值替换为 buf 里的属性值。
IPC_STAT:保存 shmid_ds 参数,把共享内存原来的属性值备份到 buf 里。
SHM_LOCK:锁定共享内存段(超级用户)。
SHM_UNLOCK:解锁共享内存段。
SHM_LOCK:用于锁定内存,禁止内存交换。并不代表共享内存被锁定后禁止其它进程访问。其真正的意义是:被锁定的内存不允许被 交换到虚拟内存中。这样做的优势在于让共享内存一直处于内存中,从而提高程序性能。
buf:shmid_ds 数据类型的地址(具体类型请点此链接 ),用来存放或修改共享内存的属性。
5.返回值:
成功:0
失败:-1
4常用命令行命令
4.1查看系统中的共享存储段
ipcs -m
4.2删除系统中的共享存储段
ipcrm -m [shmid]
5测试实例
5.1写端代码
#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 512
int main(int argc, char *argv[])
{
int shmid;
int ret;
key_t key;
char *shmadd;
//创建key值
key = ftok("../", 2015);
if(key == -1)
{
perror("ftok");
}
//创建共享内存
shmid = shmget(key, BUFSZ, IPC_CREAT|0666);
if(shmid < 0)
{
perror("shmget");
exit(-1);
}
//映射
shmadd = shmat(shmid, NULL, 0);
if(shmadd < 0)
{
perror("shmat");
_exit(-1);
}
//拷贝数据至共享内存区
printf("copy data to shared-memory\n");
bzero(shmadd, BUFSZ); // 共享内存清空
strcpy(shmadd, "how are you, mike\n");
return 0;
}
5.2读端代码
#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 512
int main(int argc, char *argv[])
{
int shmid;
int ret;
key_t key;
char *shmadd;
//创建key值
key = ftok("../", 2015);
if(key == -1)
{
perror("ftok");
}
system("ipcs -m"); //查看共享内存
//打开共享内存
shmid = shmget(key, BUFSZ, IPC_CREAT|0666);
if(shmid < 0)
{
perror("shmget");
exit(-1);
}
//映射
shmadd = shmat(shmid, NULL, 0);
if(shmadd < 0)
{
perror("shmat");
exit(-1);
}
//读共享内存区数据
printf("data = [%s]\n", shmadd);
//分离共享内存和当前进程
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;
}
5.3测试打印
zl@zl-Lenovo:~/vstdio-workspace/cmake-project/cmake-linux-learn/build$ ./writeSharedMemory 0
copy data to shared-memory
zl@zl-Lenovo:~/vstdio-workspace/cmake-project/cmake-linux-learn/build$ ./readSharedMemory 1
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0xdf0302fe 32809 zl 666 512 0
0x00000000 43 zl 606 11395950 2 dest
0x00000000 44 zl 606 11395950 2 dest
data = [how are you, mike]
deleted shared-memory
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 43 zl 606 11395950 2 dest
0x00000000 44 zl 606 11395950 2 dest
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
2
1
评论
打赏
- 分享
- 举报
评论
0个
手气红包
暂无数据
相关专栏
-
浏览量:525次2024-01-16 14:25:50
-
浏览量:192次2024-09-29 16:03:37
-
浏览量:732次2023-12-06 09:40:25
-
浏览量:852次2024-01-16 10:04:55
-
浏览量:1462次2020-08-07 17:15:53
-
浏览量:1704次2020-08-07 17:02:17
-
浏览量:1189次2023-04-17 15:56:29
-
浏览量:1947次2022-11-18 20:55:29
-
浏览量:3785次2020-08-19 16:34:45
-
浏览量:3832次2020-07-17 16:50:14
-
浏览量:1038次2023-01-12 15:24:01
-
浏览量:3086次2020-07-13 17:40:25
-
浏览量:3238次2020-08-14 18:10:33
-
浏览量:2215次2020-08-28 15:08:37
-
浏览量:928次2023-11-17 11:33:55
-
浏览量:1850次2022-05-30 09:56:07
-
浏览量:733次2024-01-25 15:08:45
-
浏览量:2393次2020-09-21 19:12:37
-
浏览量:1129次2023-12-22 14:53:36
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者
林
您的支持将鼓励我继续创作!
打赏金额:
¥1
¥5
¥10
¥50
¥100
支付方式:
微信支付
打赏成功!
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注