当前课程知识点:基于Linux的C++ >  第十三讲 进程编程 >  13.09 进程间通信(三) >  LinuxCPP1309

返回《基于Linux的C++》慕课在线视频课程列表

LinuxCPP1309在线视频

LinuxCPP1309

下一节:LinuxCPP1310

返回《基于Linux的C++》慕课在线视频列表

LinuxCPP1309课程教案、知识点、字幕

接下来的进程间通讯机制

就是共享内存

共享内存很特殊

它是一个快捷方便的本地通讯机制

它的出现比较晚

比管道 比进程信号量都要晚

共享内存有一点

在编程的时候是需要特别注意的

系统是没有对共享内存操作

定义任何同步行为的

缺省同步行为是不存在的

所以如果你需要

你就必须自主地设定

共享内存的同步行为和同步策略

你自己要能够做到这一点

典型的方式 比如讲进程信号量

我就可以做这个事

共享内存在使用的过程中

它有一个一定的逻辑

有一个规则

就是一个进程会分配一段共享内存区段

那么其它的进程呢

如果需要访问这个共享内存呢

就会查询、连接这个内存区段

这个动作我们称它为attach 叫连接

你完成了这个共享内存访问之后呢

你就可以不要了

就不连接了嘛 就拆卸

就datach这个内存区段

在某一个特定的时刻

如果所有的进程都不用这个共享内存了

那么你就可以释放共享内存区段

是按照这个模式进行工作的

在Linux操作系统下边

每一个进程 它的虚拟地址空间

是按照页进行编址的

缺省值 一个页面是4KB大小

也就是4096个字节

注意不同的硬件架构

和不同的操作系统可能是不一样的

现在我们用的是Intel 386那个架构

我们的个人电脑

它用的那个页面架构是4096个字节

你可以使用getpagesize()这个函数

来获取当前系统下页面的尺寸

每个进程都会维持从内存地址

到虚拟的这个页面地址的一个映射

多个进程可能使用同一个虚拟页面

但是同样的数据在不同的进程里边

它的地址可能并不是一样的

这有一个地址映射和变换的问题

这个地方是需要特别去注意的

你如果分配一个新的共享内存

它就会创建一个新的内存页面

其它进程呢

就可以连接这个共享内存来访问它

这样两个进程之间

不就可以通过共享内存进行通讯了吗

这是共享内存能够工作的

重要的一个地方

共享内存区段本身的分配

只能由一个进程来负责

释放也一样 你如果多个进程

都负责去管理这个共享内存区段

那不就乱了套了吗 这是不行的

这个是需要特别注意的地方

我们使用shared memory get

shmget()这个函数

来获取和分配一段共享内存

这个函数的格式和那个semget()特像

函数名字就把“h”替换了“e”

你注意看 它有一个key参数

有一个size参数 有一个shmflg参数

key还是键值

表示这个共享内存区段的

这样一个整数键值

size就是你想分配多大的

存储空间的共享内存

一般来讲 应该是页面的整数倍

4096个字节的整数倍

shmflg 就是创建这个共享内存区段的时候

它的创建标志 它特定的位标志

一般来讲 我们会使用IPC_CREAT来创建它

如果使用IPC_EXCL

这是一个独占式的创建

后者呢 就这个IPC_EXCL

会和IPC_CREAT合并使用的

如果这个键值已经使用了

那么创建就会失败了

这个很典型

如果你没有IPC_EXCL

那么它就会创建这个键值

发现这个键值已经创建了 OK

它就直接返回

那个共享内存区段的那个ID就完了

你就完成了共享

它实际上是查询一个

已经创建好的共享内存

有一些特定的位标志

可以在创建共享内存中使用

尤其是涉及到

一些用户的读写权限的地方

包括宿主用户 包括组用户

包括其他用户

你可以设定它

你比如讲 我们可以shmget()

设置一个shm_key传进去

然后get page size() 得到页的尺寸

然后以IPC_CREAT | S_IRUSR | S_IWUSER

就用户可读写的 像这样一个模式

创建一个共享内存区段

得到共享内存区段的seg_id

它的ID标识符

使用shmat()这个函数连接共享内存

传共享内存的ID

传共享内存的基地址

传连接的标志

使用shmdt() 就是detach

拆卸这个共享内存区段

你不用了 你就把它拆卸就完了

只需要传它的基地址就OK了

我们看一个具体的例子

定义一个shmid_ds的

这样一个数据结构shmbuf

然后定义一个整型seg_size

我们把共享内存区段的尺寸

固定为0x6400 这么大

然后调用shmget()

创建这个共享内存区段

创建完成之后

我们调用shmat()来连接这个共享内存区段

连接完了以后呢

我们就得到了这个共享内存区段的基地址

把它转型成指向字符指针之后

我们就可以操纵这个共享内存区段了

把它当做一个字符串一样操纵它就完了

我们就可以朝里面写入数据

当然在此过程中

可以调用shmctl()这个函数

控制那个共享内存 这是可以

这一点倒和semctl()是一样的

这是shmctl() 你可以控制它

可以得到它的信息

我们这里边用IPC_STAT得到它的信息

接下来我们可以

向共享内存区段写入数据

传那个基地址shared_mem进去

就可以向那个缓冲区里面写数据了

这个写入就好像你定义了

一个字符数组

或者是定义一个字符指针

然后new一段存储区出来

朝里面写数据 一样

然后用完了

shmdt() 就把shared_mem清掉

接下来可以重新地

把它连接到一个新的不同的区段

shared__mem 可以

然后重新连接 重新去访问它

用完了 再把它detach掉 OK

最后销毁它

用shmctl()调用传IPC_RMID

销毁这个ID所对应的共享内存区段

释放它 OK

这就是使用共享内存的最基本的策略

基于Linux的C++课程列表:

第一讲 C/C++基本语法元素

-1.1 提纲

--LinuxCPP0101

-1.2 程序设计的基本概念

--LinuxCPP0102

-1.3 简单C/C++程序介绍

--LinuxCPP0103

-1.4 程序设计的基本流程

--LinuxCPP0104

-1.5 基本语法元素

--LinuxCPP0105

-1.6 程序设计风格

--LinuxCPP0106

-1.7 编程实践

--LinuxCPP0107

-第一讲 C/C++基本语法元素--编程实践提交入口

第二讲 程序控制结构

-2.1 提纲

--LinuxCPP0201

-2.2 结构化程序设计基础

--LinuxCPP0202

-2.3 布尔数据

--LinuxCPP0203

-2.4 分支结构

--LinuxCPP0204

-2.5 break语句

--LinuxCPP0205

-2.6 循环结构

--LinuxCPP0206

-2.7 编程实践

--LinuxCPP0207

-第二讲 程序控制结构--编程实践提交入口

第三讲 函数

-3.1 提纲

--LinuxCPP0301

-3.2 函数声明、调用与定义

--LinuxCPP0302

-3.3 函数调用栈框架

--LinuxCPP0303

-3.4 编程实践

--LinuxCPP0304

-第三讲 函数--编程实践提交入口

第四讲 算法

-4.1 提纲

--LinuxCPP0401

-4.2 算法概念与特征

--LinuxCPP0402

-4.3 算法描述

--LinuxCPP0403

-4.4 算法设计与实现

--LinuxCPP0404

-4.5 递归算法(一)

--LinuxCPP0405

-4.6 递归算法(二)

--LinuxCPP0406

-4.7 容错与计算复杂度

--LinuxCPP0407

-4.8 编程实践

--LinuxCPP0408

-第四讲 算法--编程实践提交入口

第五讲 程序组织与开发方法

-5.1 提纲

--LinuxCPP0501

-5.2 库与接口

--LinuxCPP0502

-5.3 随机数库(一)

--LinuxCPP0503

-5.4 随机数库(二)

--LinuxCPP0504

-5.5 作用域与生存期

--LinuxCPP0505

-5.6 典型软件开发流程(一)

--LinuxCPP0506

-5.7 典型软件开发流程(二)

--LinuxCPP0507

-5.8 编程实践

--LinuxCPP0508

-第五讲 程序组织与开发方法--编程实践提交入口

第六讲 复合数据类型

-6.1 提纲

--LinuxCPP0601

-6.2 字符

--LinuxCPP0602

-6.3 数组(一)

--LinuxCPP0603

-6.4 数组(二)

--LinuxCPP0604

-6.5 结构体

--LinuxCPP0605

-6.6 编程实践

--LinuxCPP0606

-第六讲 复合数据类型--编程实践提交入口

第七讲 指针与引用

-7.1 提纲

--LinuxCPP0701

-7.2 指针基本概念

--LinuxCPP0702

-7.3 指针与函数

--LinuxCPP0703

-7.4 指针与复合数据类型(一)

--LinuxCPP0704

-7.5 指针与复合数据类型(二)

--LinuxCPP0705

-7.6 字符串

--LinuxCPP0706

-7.7 动态存储管理(一)

--LinuxCPP0707

-7.8 动态存储管理(二)

--LinuxCPP0708

-7.9 引用

--LinuxCPP0709

-7.10 编程实践

--LinuxCPP0710

-第七讲 指针与引用--编程实践提交入口

第八讲 链表与程序抽象

-8.1 提纲

--LinuxCPP0801

-8.2 数据抽象(一)

--LinuxCPP0802

-8.3 数据抽象(二)

--LinuxCPP0803

-8.4 链表(一)

--LinuxCPP0804

-8.5 链表(二)

--LinuxCPP0805

-8.6 链表(三)

--LinuxCPP0806

-8.7 链表(四)

--LinuxCPP0807

-8.8 函数指针(一)

--LinuxCPP0808

-8.9 函数指针(二)

--LinuxCPP0809

-8.10 抽象链表(一)

--LinuxCPP0810

-8.11 抽象链表(二)

--LinuxCPP0811

-8.12 编程实践

--LinuxCPP0812

-第八讲 链表与程序抽象--编程实践提交入口

第九讲 类与对象

-9.1 提纲

--LinuxCPP0901

-9.2 程序抽象与面向对象

--LinuxCPP0902

-9.3 类类型

--LinuxCPP0903

-9.4 对象(一)

--LinuxCPP0904

-9.5 对象(二)

--LinuxCPP0905

-9.6 类与对象的成员(一)

--LinuxCPP0906

-9.7 类与对象的成员(二)

--LinuxCPP0907

-9.8 类与对象的成员(三)

--LinuxCPP0908

-9.9 继承(一)

--LinuxCPP0909

-9.10 继承(二)

--LinuxCPP0910

-9.11 继承(三)

--LinuxCPP0911

-9.12 多态(一)

--LinuxCPP0912

-9.13 多态(二)

--LinuxCPP0913

-9.14 编程实践

--LinuxCPP0914

-第九讲 类与对象--编程实践提交入口

第十讲 操作符重载

-10.1 提纲

--LinuxCPP1001

-10.2 四则运算符重载(一)

--LinuxCPP1002

-10.3 四则运算符重载(二)

--LinuxCPP1003

-10.4 关系与下标操作符重载

--LinuxCPP1004

-10.5 赋值操作符重载(一)

--LinuxCPP1005

-10.6 赋值操作符重载(二)

--LinuxCPP1006

-10.7 赋值操作符重载(三)

--LinuxCPP1007

-10.8 赋值操作符重载(四)

--LinuxCPP1008

-10.9 赋值操作符重载(五)

--LinuxCPP1009

-10.10 流操作符重载(一)

--LinuxCPP1010

-10.11 流操作符重载(二)

--LinuxCPP1011

-10.12 流操作符重载(三)

--LinuxCPP1012

-10.13 操作符重载总结

--LinuxCPP1013

-10.14 编程实践

--LinuxCPP1014

-第十讲 操作符重载--编程实践提交入口

第十一讲 泛型编程

-11.1 提纲

--LinuxCPP1101

-11.2 泛型编程概览

--LinuxCPP1102

-11.3 异常处理机制(一)

--LinuxCPP1103

-11.4 异常处理机制(二)

--LinuxCPP1104

-11.5 运行期型式信息(一)

--LinuxCPP1105

-11.6 运行期型式信息(二)

--LinuxCPP1106

-11.7 模板与型式参数化

--LinuxCPP1107

-11.8 题外话:术语翻译

--LinuxCPP1108

-11.9 泛型编程实践(一)

--LinuxCPP1109

-11.10 泛型编程实践(二)

--LinuxCPP1110

-11.11 泛型编程实践(三)

--LinuxCPP1111

-11.12 泛型编程实践(四)

--LinuxCPP1112

-11.13 泛型编程实践(五)

--LinuxCPP1113

-11.14 泛型编程实践(六)

--LinuxCPP1114

-11.15 泛型编程实践(七)

--LinuxCPP1115

-11.16 泛型编程实践(八)

--LinuxCPP1116

-11.17 泛型编程实践(九)

--LinuxCPP1117

-11.18 泛型编程实践(十)

--LinuxCPP1118

-11.19 编程实践

--LinuxCPP1119

-第十一讲 泛型编程--编程实践提交入口

第十二讲 Linux系统编程基础

-12.1 提纲

--LinuxCPP1201

-12.2 程序执行环境(一)

--LinuxCPP1202

-12.3 程序执行环境(二)

--LinuxCPP1203

-12.4 程序执行环境(三)

--LinuxCPP1204

-12.5 程序执行环境(四)

--LinuxCPP1205

-12.6 输入输出(一)

--LinuxCPP1206

-12.7 输入输出(二)

--LinuxCPP1207

-12.8 文件系统

--LinuxCPP1208

-12.9 设备

--LinuxCPP1209

-12.10 库(一)

--LinuxCPP1210

-12.11 库(二)

--LinuxCPP1211

-12.12 makefile文件(一)

--LinuxCPP1212

-12.13 makefile文件(二)

--LinuxCPP1213

-12.14 makefile文件(三)

--LinuxCPP1214

-12.15 编程实践

--LinuxCPP1215

-第十二讲 Linux系统编程基础--编程实践提交入口

第十三讲 进程编程

-13.01 提纲

--LinuxCPP1301

-13.02 进程基本概念

--LinuxCPP1302

-13.03 信号

--LinuxCPP1303

-13.04 进程管理(一)

--LinuxCPP1304

-13.05 进程管理(二)

--LinuxCPP1305

-13.06 进程管理(三)

--LinuxCPP1306

-13.07 进程间通信(一)

--LinuxCPP1307

-13.08 进程间通信(二)

--LinuxCPP1308

-13.09 进程间通信(三)

--LinuxCPP1309

-13.10 进程间通信(四)

--LinuxCPP1310

-13.11 进程池

--LinuxCPP1311

-13.12 编程实践

--LinuxCPP1312

-第十三讲 进程编程--编程实践提交入口

第十四讲 线程编程

-14.1 提纲

--LinuxCPP1401

-14.2 线程基本概念

--LinuxCPP1402

-14.3 线程管理(一)

--LinuxCPP1403

-14.4 线程管理(二)

--LinuxCPP1404

-14.5 线程管理(三)

--LinuxCPP1405

-14.6 线程管理(四)

--LinuxCPP1406

-14.7 线程同步机制(一)

--LinuxCPP1407

-14.8 线程同步机制(二)

--LinuxCPP1408

-14.9 C++11线程库(一)

--LinuxCPP1409

-14.10 C++11线程库(二)

--LinuxCPP1410

-14.11 C++11线程库(三)

--LinuxCPP1411

-14.12 C++11线程库(四)

--LinuxCPP1412

-14.13 C++11线程库(五)

--LinuxCPP1413

-14.14 编程实践

--LinuxCPP1414

-第十四讲 线程编程--编程实践提交入口

第十五讲 网络编程

-15.1 提纲

--LinuxCPP1501

-15.2 Internet网络协议

--LinuxCPP1502

-15.3 套接字(一)

--LinuxCPP1503

-15.4 套接字(二)

--LinuxCPP1504

-15.5 编程实践

--LinuxCPP1505

-第十五讲 网络编程--编程实践提交入口

课程文档

-课程PDF文件

LinuxCPP1309笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。