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 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux进程间通信之共享内存(七) -> 正文阅读

[系统运维]Linux进程间通信之共享内存(七)

1.共享内存原理

共享内存允许两个或者多个进程共享给定的存储区域。 共享内存的特点 1、共享内存是进程间共享数据的一种最快的方法。一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。 2、使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥。 若一个进程正在向共享内存区写数据,则在它做完这一步操作前,别的进程不应当去读、写这些数据。

1.1.共享内存示意图:

在这里插入图片描述
在ubuntu 部分版本中共享内存限制值如下 共享存储区的最小字节数:1 共享存储区的最大字节数:32M 共享存储区的最大个数:4096 每个进程最多能映射的共享存储区的个数:4096

2.共享内存的创建和使用

2.1获得一个共享存储标识符

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

功能:
创建或打开一块共享内存区。

参数:
key:IPC键值。
size:该共享存储段的长度(字节)。
shmflg:标识函数的行为及共享内存的权限。

shmflg说明:
PC_CREAT:如果不存在就创建
IPC_EXCL:如果已经存在则返回失败
位或权限位:共享内存位或权限位后可以设置共享内存的访问权限,格式和open函数的mode_t一样,但可执行权限未使用。

返回值:
成功:返回共享内存标识符。
失败:返回 -1。

操作:
使用shell命令操作共享内存: 查看共享内存 ipcs -m 删除共享内存 ipcrm -m shmid

2.2.共享区映射

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

功能:
将一个共享内存段映射到调用进程的数据段中。

参数:
shmid:共享内存标识符。
shmaddr:共享内存映射地址(若为NULL则由系统自动指定),推荐使用NULL。
shmflg:共享内存段的访问权限和映射条件。

shmflg说明:
0:共享内存具有可读可写权限。
SHM_RND:(shmaddr非空时才有效)。
没有指定SHM_RND则此段连接到shmaddr所指定的地址上(shmaddr必需页对齐)。
指定了SHM_RND则此段连接到shmaddr- shmaddr%SHMLBA 所表示的地址上。

返回值:
成功:返回共享内存段映射地址。
失败:返回 -1。

注意:
shmat函数使用的时候第二个和第三个参数一般设为NULL和0,即系统自动指定共享内存地址,并且共享内存可读可写。

2.3.解除共享映射区

	int shmdt(const void *shmaddr);

功能:
将共享内存和当前进程分离(仅仅是断开联系并不删除共享内存)。

参数:
shmaddr:共享内存映射地址。

返回值:
成功:返回0。
失败:返回 -1。

2.4.共享内存控制

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

功能:
共享内存空间的控制。

参数:
shmid:共享内存标识符。
cmd:函数功能的控制。
buf:shmid_ds数据类型的地址,用来存放或修改共享内存的属性。

cmd说明:
IPC_RMID:删除。
IPC_SET:设置shmid_ds参数。
IPC_STAT:保存shmid_ds参数。
SHM_LOCK:锁定共享内存段(超级用户)。
SHM_UNLOCK:解锁共享内存段。

返回值:
成功:返回0。
失败:返回 -1。

注意:
SHM_LOCK用于锁定内存,禁止内存交换。并不代表共享内存被锁定后禁止其它进程访问。其真正的意义是:被锁定的内存不允许被交换到虚拟内存中。 这样做的优势在于让共享内存一直处于内存中,从而提高程序性能.

3.参考代码

3.1.共享内存读操作

//=============================================================================
// File Name    : process_shmread.c
// Author       : FengQQ
//
// Description  : 共享内存读数据
// Annotation   : 
//
// Created by FengQQ. 2020-10-03
//=============================================================================
#include <stddef.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "shmdata.h"

int main(int argc,char *argv[])
{
	int ret;
	int shmid;
	void *shm = NULL;
	struct shared_use_st *shared; 	// 指向shm
	
	shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);
	if(shmid < 0)
	{
		printf("shmget failed...\r\n");
		exit(EXIT_FAILURE);
	}
	
	shm = shmat(shmid,0,0);
	if(shm < 0)
	{
		printf("shmat failed...\r\n");
		exit(EXIT_FAILURE);
	}
	
	printf("\nMemory attached at %X\n", (int)shm);
	
	shared = (struct shared_use_st *)shm;
	shared->written =0;	
	
	while(1)
	{
		if(shared->written == 1)
		{
			printf("You wrote: %s",shared->text);
			sleep(1);
			
			shared->written = 0;
			
			if(strncmp(shared->text,"end",3) == 0)
			{
				break;
			}
		}
		else
		{
			sleep(1);
		}
	}
	
	ret = shmdt(shm);
	if(ret < 0)
	{
		printf("shmdt failed...\r\n");
		exit(EXIT_FAILURE);
	}
	
	ret = shmctl(shmid,IPC_RMID,0);
	if(ret < 0)
	{
		printf("shmctl(IPC_RMID) failed...\r\n");
		exit(EXIT_FAILURE);
	}
	
	exit(EXIT_SUCCESS);
	
	return 0;
}

3.2.共享内存写操作

//=============================================================================
// File Name    : process_shmwrite.c
// Author       : FengQQ
//
// Description  : 共享内存写数据
// Annotation   : 
//
// Created by FengQQ. 2020-10-03
//=============================================================================
#include <stddef.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "shmdata.h"

int main(int argc,char *argv[])
{
	int ret;
	int shmid;
	void *shm = NULL;
	struct shared_use_st *shared = NULL;
	char buffer[BUFSIZ + 1];				//用于保存输入的文本
	
	shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);// 创建共享内存
	if(shmid < 0)
	{
		printf("shmget failed...\r\n");
		exit(EXIT_FAILURE);
	}
	
	shm = shmat(shmid,(void *)0,0);			 // 将共享内存连接到当前的进程地址空间
	if(shm < 0)
	{
		printf("shmat failed...\r\n");
		exit(EXIT_FAILURE);
	}
	
	printf("Memory attched at %X\n", (int)shm);
	
	shared = (struct shared_use_st *)shm;	//设置共享内存
	while(1)								//向共享内存中写数据
	{
		while(shared->written  == 1)		//数据还没有被读取,则等待数据被读取,不能向共享内存中写入文本
		{
			sleep(1);
			printf("Waiting...\r\n");
		}
		printf("Enter some text: ");		//向共享内存中写入数据
		fgets(buffer,BUFSIZ,stdin);			//从键盘中获取输入的字符串
		strncpy(shared->text,buffer,TEXT_SZ);
		
		shared->written = 1;				//写完数据,设置written使共享内存段可读
		if(strncmp(buffer,"end",3) == 0)	//输入了end,退出循环(程序)
		{
			break;
		}
	}
	if(shmdt(shm) == -1)					//把共享内存从当前进程中分离
	{
		printf("shmdt failed...\r\n");
	}
	
	sleep(2);
	exit(EXIT_SUCCESS);
	
	return 0;
}

3.3…共享内存头文件

#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

**注意:**需要开启两个终端,先运行写操作,再运行读操作,然后再写操作运行之后输入数据,并回车,可在读操作看到对应得数据。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 17:05:23  更:2021-08-12 17:06:57 
 
开发: 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/20 11:16:50-

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