进程通信——通过共享内存实现

本文介绍了在Linux系统中如何使用C语言通过共享内存实现进程间的通信,包括内存共享的概念、原理、实现方法、存在的问题及解决措施。详细讲解了共享内存的创建、映射、脱离和控制函数,并给出了简单通信的示例代码。
摘要由CSDN通过智能技术生成

Linux系统中用c通过共享内存实现进程通信

一、内存共享

1、什么是内存共享

就是OS在物理内存中开辟一大段缓存空间,进程直接使用地址来共享读写的。
与管道、消息队列调用API来读写不同。
因为直接读取内存中的数据,所以共享内存的通信方式快
而管道、消息队列的通信方式慢

2、内存共享的原理

本来每个进程都严格对应不相交的物理地址,所以交流很困难
所以原理很简单:要想实现通信,让他们的进程空间有交集就行了
在这里插入图片描述

3、共享内存的实现方法

以两个进程使用共享内存来通信为例:
1、调用API,让OS在物理内存上开辟出一大段缓存空间
2、让各自进程空间与开辟出的缓存空间建立映射关系

建立了映射关系后,每个进程都可以通过映射后的虚拟地址来共享操作实现通信了

4、共享内存存在的问题

当实现多个进程映射到同一片空间进行数据共享时,在写数据时就会出现互相干扰。

比如A进程写一半时切到B进程造成A的数据被打断。因为CPU都是不停的在不同进程之间切换运行,每个进程都有自己的时间片,本来A进程被打断后,等下次重新恢复运行时继续在自己内存上写数据,但是因为和B进程共享内存,导致在A打断期间运行B时也写入了数据,也是写入到与A的共享内存上,等恢复A运行时,其内存上已经写入了其他数据(B写入的)。这样就造成数据的错误。

这就需要加保护措施,这里先不对此详细叙述

5、共享内存的使用步骤

  1. 调用shmget函数创建或获取已有的共享内存
  2. 调用shmat函数,将物理内存映射到自己的进程空间,就可以使用虚拟地址来读写共享的内存空间了
  3. shmdt函数,取消映射
  4. 调用shmctl函数释放开辟的物理内存空间
    多个进程使用共享内存时,创建者只需要一个,一般是第一个,其后其他进程发现已经建好了,直接获取使用

6、共享内存的函数

1. shmget

int shmget(key_t key, size_t size, int shmflg);

功能:创建新的,或者获取已有的共性内存,在于key值
参数:
a)key:用于生成共享内存的标识号,可以有三种设置
b)size:指定共享内存的大小,要求size是虚拟页大小的整数倍
c)semflg:创建时用 IPC_CREAT|0644 打开直接是0
返回值:成功返回一个非负证书,即该共享内存段的标识码;失败返回-1.

2. shmat

void *shmat(int shmid, const void *shmaddr, int shmflg);

功能:将共享内存段连接到进程地址空间
参数:
a)shmid:共享内存标识
b)shmaddr:指定连接地址
c)shmflg:SHM_RND或SHM_RDONLY
返回值: 成功返回一个指针,指向共享内存第一个节;失败返回-1.

3. shmdt
>int shmdt(const void *shmaddr);

功能:将共享内存与当前进程脱离

参数:
a) shmaddr:由shmad所返回的指针
返回值: 成功返回0,失败返回-1.
注意:将共享内存与当前进程脱离不等于删除共享内存段

4. shmctl

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

功能:用于控制共享内存
参数:
shmid: 由shmget返回的共享内存标识码
cmd:将要采取的动作(由三个可取的值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值: 成功返回0,失败返回-1.

二、在Linux中实现简单的内存共享通信

1、创建内存共享的c语言程序

其中创建共享内存在read.c中实现,所以需要先执行read.c程序

shmdata.h的源代码
#ifndef _SHMDATA_H_HEADER
#define _SHMDATA_H_HEADER
 
#define TEXT_SZ 2048
 
struct shared_use_st
{
   
	int written;//作为一个标志,非0:表示可读,0表示可写
	char text[TEXT_SZ];//记录写入和读取的文本
};
 
#endif
源文件read.c的源代码如下:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include "shmdata.h"
 
int main()
{
   
	int running = 1;//程序是否继续运行的标志
	void *shm = NULL;<
  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值