第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课-共享内存通讯相关推荐

  1. [国嵌攻略][085][共享内存通讯]

    共享内存 共享内存是IPC机制中的一种,它允许两个相关的进程访问同一段内存,这是传递数据的一种有效的方式. A.c #include <sys/types.h> #include < ...

  2. 共享内存大数据量快速进程间通讯

    最近在做一个进程间频繁,数据量比较大的通讯 采用的是共享内存通讯,和生产者消费者模式.调试了几天,记录一些要点 结构如下图 注意: 1.因为是共享,如果进程B有多个对象要写数据到共享内存,每次写入计数 ...

  3. 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...

  4. MFC:通过代码简单理解进程间的通讯机制——共享内存

    下面用共享映射文件的方式实现进程间通信,代码可以运行. 一.浅理解 每个进程有自己独立的空间,一个进程无法访问其他进程的数据.就好像两个是互不干涉的个体,想让它们进行通信(交换数据),就必须有一段它们 ...

  5. QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开     本文地址:h ...

  6. linux open 头文件_linux下通过共享内存和mmap实现进程间通讯

    前言 最近在学习GNU/Linux内核,看到mmap的时候书上说: mmap/munmap接口函数是用户最常用的两个系统调用接口,无论是在用户程序中分配内存.读写大文件.链接动态库文件,还是多进程间共 ...

  7. RTX5 | 内存池04 - 共享内存用于线程之间的通讯(阻塞方式)- 使用信号量

    文章目录 一.前言 二.实验目的 三.代码 3.1.main.h 3.2.main.c 四.Debug 4.1.System Analyzer 4.2.Debug (printf) Viewer 一. ...

  8. RTX5 | 内存池03 - 共享内存用于线程之间的通讯(轮询方式)

    文章目录 一.前言 怎样防止内存溢出? 二.实验目的 三.代码 3.1.main.h 3.2.main.c 四.Debug 4.1.Debug (printf) Viewer 4.2.修改一下程序:线 ...

  9. linux mmap实例_Linux下通过共享内存和mmap实现进程间通讯(含实例)

    前言 最近在学习GNU/Linux内核,看到mmap的时候书上说: mmap/munmap接口函数是用户最常用的两个系统调用接口,无论是在用户程序中分配内存.读写大文件.链接动态库文件,还是多进程间共 ...

  10. Linux 进程间通讯(IPC)方式 ------- 共享内存

    Linux 进程间通讯(IPC)方式有以下几种: 1->管道(pipe)和有名管道(fifo). 2->消息队列 3->共享内存 4->信号量 5->信号(signal) ...

最新文章

  1. 华为手机设置代理网络就无法使用_华为手机一定要了解的7个设置!1秒开启使用,实在太强大了...
  2. python语言必背代码-Python新手必须知道的25条知识点
  3. 温州大学《机器学习》课程课件和视频(四)朴素贝叶斯
  4. swoole 清除定时器提示no timer
  5. 远程桌面mstsc命令参数的使用
  6. cpu不支持虚拟装linux,linux 查看cpu是不是支持虚拟化
  7. fedora ssh 安装mysql,Fedora中安装和配置OpenSSH | 学步园
  8. 怎么检测不到我的音频_Linux 上的最佳音频编辑工具推荐 | Linux 中国
  9. 可输入过滤和直接选择的select控件
  10. 语言 双线性内插_数位语音信号处理概论 Lesson6 语言模型
  11. 盘点 | 2017 年关于 Python 的 12 件大事
  12. Notefile for Mac(记事本工具)支持12系统
  13. 我是怎样给 Delphi 代码着色的 - 回复 sunhj 的问题
  14. tp51 自定义404界面的配置
  15. Win10怎么提高显卡游戏性能
  16. 自定义TimePicker样式,修改时分、分割线分隔冒号的字体、颜色高度等属性
  17. 微信域名防封、域名检测接口api、域名跳转技术、360防拦截揭秘(二)------传统防封的弊端
  18. 宝塔linux怎么安装asp网站,宝塔面板创建网站:宝塔linux面板添加网站详细教程...
  19. excel换行按什么键_电脑截图按什么键
  20. 实用一位加法电路-全加器(全加器真值表、全加器的逻辑组合电路)、几种基本组合逻辑电路真值表 补充:逻辑电路基础:与门、或门、非门----计算机组成原理

热门文章

  1. Androrid Studio Debug Warning:debug info can be unavailable
  2. php mysql源码包,linux下Apache+PHP+mysql+phpMyAdmin源码包安装配置
  3. laravel mysql rand_Laravel-雄辩或流利的随机行
  4. Flink Forward Asia 2019 - 总结和展望(附PPT下载链接)
  5. Java中的 BigDecimal,80%的人都用错了....
  6. 除了微软默认的ppt服务器外,微软如此解释这一新政。据了解,除了MSN与Skype有很多类似功能之外.ppt...
  7. 属于db模式缺点的是什么_DB与ES混合之应用系统场景分析探讨
  8. mysql sha1prng_为啥POST过来的
  9. 对无焦点窗口模拟按键_键盘不为人知的一面——单按键篇
  10. python自定义标识符_《Python 3程序开发指南(第2版•修订版)》——第2章 数据类型 2.1 标识符与关键字...