第三季-第18课-共享内存通讯
第18课-共享内存通讯
18.1 基本概念
共享内存是IPC机制中的一种. 顾名思义,它允许两个不相关的进程访问同一段内存,这是传递数据的一种非常有效的方式。即,可以让进程A和B同时访问一段内存。
18.2 函数学习
1. 创建/获取共享内存
(1)函数名
shmget
(2)函数原型
int shmget(key_t key, size_t size ,int shmflg);
(3)函数功能
创建或者获取共享内存,并返回其描述符。(allocates a shared memory segment)。
(4)所属头文件
#include<sys/ipc.h>
#include<sys/shm.h>
(5)返回值
成功:返回创建或者获取到的共享内存的描述符
失败:-1
(6)参数说明
key:共享内存的键值
size:共享内存的大小
shnflg:打开标志,如果使用了IPC_CREAT这个标志,就会新创建一个共享内存。
2. 映射共享内存
(1)函数名
shmat
(2)函数原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
(3)函数功能
把shmid指定的共享内存映射到进程的地址空间里。(shared memory operations)。
(4)所属头文件
#include<sys/types.h>
#include<sys/shm.h>
(5)返回值
成功:返回映射到进程空间之后的内存地址
失败:-1
(6)参数说明
shmid:要映射的共享内存的描述符
shmaddr:指定映射之后的地址,一般的情况下,改参数都是NULL,表明让linux系统自动的选择地址
shmflg:标志
3. 分离(脱离)共享内存
(1)函数名
shmdt
(2)函数原型
int shmdt(const void *shmaddr);
(3)函数功能
从进程地址空间中,断掉与共享内存的联系。(shared memory operations)。
(4)所属头文件
#include<sys/types.h>
#include<sys/shm.h>
(5)返回值
成功:0
失败:-1
(6)参数说明
shmaddr:要断开的共享内存的地址
4. 删除(控制)共享内存
(1)函数名
shmctl
(2)函数原型
int shmctl(int shmid, int cmd, sruct shmid_ds *buf);
(3)函数功能
控制共享内存(performs the control operation specified by cmd on the shared memory segment whose identifier is given in shmid)。
(4)所属头文件
#include<sys/ipc.h>
#include<sys/shm.h>
(5)返回值
成功:0
失败:-1
(6)参数说明
shmid:要控制的共享内存的id
cmd:决定执行什么样的控制操作,如IPC_RMID(表示删除)
内核为每一个共享存储段设置了一个shmid_ds结构,该结构如下:
struct shmid_ds {
struct ipc_perm shm_perm; /*see Section 15.6.2*/
size_t shm_segsz; /*size of segment in bytes*/
pid_t shm_lpid; /*pid of last shmop*/
shmatt_t shm_nattch; /*number of current attaches*/
time_t shm_atime; /*last-attach time*/
time_t shm_dtime; /*last-detach time*/
time_t shm_ctime; /*last-change time*/
(按照支持共享存储段的需要,每种实现会在shmid_ds结构中增加其他成员)
buf:获取linux中描述共享内存的shmid_ds结构。基本不使用。
18.3 综合实例
1. 流程:
A和B两个进程,A先创建一个共享内存,然后再映射该共享内存。对于B进程先获取共享内存,然后再映射该共享内存。当用完了该共享内存后,A和B进程再分别分离该共享内存。A进程去删除共享内存。
2. 程序解读
我们设置两个进程,一个write进程,一个read进程。前一个进程是读取键盘上的输入的字符串,并且把字符串保存在共享内存之中。后一个进程的作用是,在共享内存中读取字符串,并且打印它们。
write进程的流程:(1)创建共享内存;(2)映射共享内存;(3)获取用户输入,把字符串放入共享内存,循环来做直到用户终止;(4)脱离共享内存。
write.c:
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#define TEXT_SZ 2048
struct shared_use_st
{
int written_by_you;
char some_text[TEXT_SZ];
};
int main()
{
int running = 1; //定义循环标志
key_t key;
key = ftok("/root",3);
int shmid;
struct shared_use_st *shared_stuff;
char buffer[TEXT_SZ]; //fgets()函数用到的存储用的数组
//1.创建共享内存;
shmid = shmget(key, sizeof(struct shared_use_st),IPC_CREAT);
if(shmid == -1)
{
printf("creat share memory fail!\n");
exit(EXIT_FAILURE); //退出的标志
}
//2.映射共享内存.
shared_stuff = (struct shared_use_st *)shmat(shmid, NULL, 0); //强制转换
//3.循环
while(running)
{
//观看数据有没有被取走,没被取走一直等待
while(shared_stuff->written_by_you == 1)
{
sleep(1);
printf("wait read process!\n");
}
//3.1 获取用户输入
fgets(buffer,TEXT_SZ,stdin); // char *fgets(char *s, int szie FILE *stream);
//3.2把字符串放入共享内存
strncpy(shared_stuff->some_text,buffer,TEXT_SZ);
shared_stuff->written_by_you = 1;
if(strncmp(buffer,"end",3)==0)
{
running = 0;
}
}
//4.脱离共享内存
shmdt((const void *)shared_stuff); //强制转换
return 1;
}
read进程流程:(1)创建/获取共享内存;(2)映射共享内存;(3)循环,打印共享内存中的字符串,直到收到结束的通知;(4)脱离共享内存;(5)删除共享内存。
read.c
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#define TEXT_SZ 2048
struct shared_use_st
{
int written_by_you;
char some_text[TEXT_SZ];
};
int main()
{
int running = 1; //定义循环标志
int shmid;
key_t key;
key = ftok("/root",3);
struct shared_use_st *shared_stuff;
char buffer[TEXT_SZ];
//1.创建/获取共享内存;
shmid = shmget(key, sizeof(struct shared_use_st),IPC_CREAT);
//2.映射共享内存;
shared_stuff = (struct shared_use_st *)shmat(shmid, NULL, 0); //强制转换
shared_stuff->written_by_you = 0; //最初的标识是0;
//3.循环
while(running)
{
//打印共享内存中的字符串,直到收到结束的通知;
if(shared_stuff->written_by_you == 1)
{
printf("write process is %s\n",shared_stuff->some_text);
shared_stuff->written_by_you = 0;
if(strncmp(shared_stuff->some_text,"end",3)==0)
running = 0;
}
}
//4.脱离共享内存;
shmdt((const void *)shared_stuff); //强制转换
//5.删除共享内存。
shmctl(shmid,IPC_RMID,0);
return 1;
}
运行结果:在两个一样的终端中,先运行./read,在运行./write。我们在./write中输入的字符串会在./read中显示,直到输入end,两个程序都停止。
转载于:https://www.cnblogs.com/free-1122/p/11352554.html
第三季-第18课-共享内存通讯相关推荐
- [国嵌攻略][085][共享内存通讯]
共享内存 共享内存是IPC机制中的一种,它允许两个相关的进程访问同一段内存,这是传递数据的一种有效的方式. A.c #include <sys/types.h> #include < ...
- 共享内存大数据量快速进程间通讯
最近在做一个进程间频繁,数据量比较大的通讯 采用的是共享内存通讯,和生产者消费者模式.调试了几天,记录一些要点 结构如下图 注意: 1.因为是共享,如果进程B有多个对象要写数据到共享内存,每次写入计数 ...
- 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...
- MFC:通过代码简单理解进程间的通讯机制——共享内存
下面用共享映射文件的方式实现进程间通信,代码可以运行. 一.浅理解 每个进程有自己独立的空间,一个进程无法访问其他进程的数据.就好像两个是互不干涉的个体,想让它们进行通信(交换数据),就必须有一段它们 ...
- QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开 本文地址:h ...
- linux open 头文件_linux下通过共享内存和mmap实现进程间通讯
前言 最近在学习GNU/Linux内核,看到mmap的时候书上说: mmap/munmap接口函数是用户最常用的两个系统调用接口,无论是在用户程序中分配内存.读写大文件.链接动态库文件,还是多进程间共 ...
- RTX5 | 内存池04 - 共享内存用于线程之间的通讯(阻塞方式)- 使用信号量
文章目录 一.前言 二.实验目的 三.代码 3.1.main.h 3.2.main.c 四.Debug 4.1.System Analyzer 4.2.Debug (printf) Viewer 一. ...
- RTX5 | 内存池03 - 共享内存用于线程之间的通讯(轮询方式)
文章目录 一.前言 怎样防止内存溢出? 二.实验目的 三.代码 3.1.main.h 3.2.main.c 四.Debug 4.1.Debug (printf) Viewer 4.2.修改一下程序:线 ...
- linux mmap实例_Linux下通过共享内存和mmap实现进程间通讯(含实例)
前言 最近在学习GNU/Linux内核,看到mmap的时候书上说: mmap/munmap接口函数是用户最常用的两个系统调用接口,无论是在用户程序中分配内存.读写大文件.链接动态库文件,还是多进程间共 ...
- Linux 进程间通讯(IPC)方式 ------- 共享内存
Linux 进程间通讯(IPC)方式有以下几种: 1->管道(pipe)和有名管道(fifo). 2->消息队列 3->共享内存 4->信号量 5->信号(signal) ...
最新文章
- 华为手机设置代理网络就无法使用_华为手机一定要了解的7个设置!1秒开启使用,实在太强大了...
- python语言必背代码-Python新手必须知道的25条知识点
- 温州大学《机器学习》课程课件和视频(四)朴素贝叶斯
- swoole 清除定时器提示no timer
- 远程桌面mstsc命令参数的使用
- cpu不支持虚拟装linux,linux 查看cpu是不是支持虚拟化
- fedora ssh 安装mysql,Fedora中安装和配置OpenSSH | 学步园
- 怎么检测不到我的音频_Linux 上的最佳音频编辑工具推荐 | Linux 中国
- 可输入过滤和直接选择的select控件
- 语言 双线性内插_数位语音信号处理概论 Lesson6 语言模型
- 盘点 | 2017 年关于 Python 的 12 件大事
- Notefile for Mac(记事本工具)支持12系统
- 我是怎样给 Delphi 代码着色的 - 回复 sunhj 的问题
- tp51 自定义404界面的配置
- Win10怎么提高显卡游戏性能
- 自定义TimePicker样式,修改时分、分割线分隔冒号的字体、颜色高度等属性
- 微信域名防封、域名检测接口api、域名跳转技术、360防拦截揭秘(二)------传统防封的弊端
- 宝塔linux怎么安装asp网站,宝塔面板创建网站:宝塔linux面板添加网站详细教程...
- excel换行按什么键_电脑截图按什么键
- 实用一位加法电路-全加器(全加器真值表、全加器的逻辑组合电路)、几种基本组合逻辑电路真值表 补充:逻辑电路基础:与门、或门、非门----计算机组成原理
热门文章
- Androrid Studio Debug Warning:debug info can be unavailable
- php mysql源码包,linux下Apache+PHP+mysql+phpMyAdmin源码包安装配置
- laravel mysql rand_Laravel-雄辩或流利的随机行
- Flink Forward Asia 2019 - 总结和展望(附PPT下载链接)
- Java中的 BigDecimal,80%的人都用错了....
- 除了微软默认的ppt服务器外,微软如此解释这一新政。据了解,除了MSN与Skype有很多类似功能之外.ppt...
- 属于db模式缺点的是什么_DB与ES混合之应用系统场景分析探讨
- mysql sha1prng_为啥POST过来的
- 对无焦点窗口模拟按键_键盘不为人知的一面——单按键篇
- python自定义标识符_《Python 3程序开发指南(第2版•修订版)》——第2章 数据类型 2.1 标识符与关键字...